You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python RegEx的finditer提取键值对时匹配不全的问题排查

从字符串提取顶层$开头键值对的正则问题

我有一段包含多组键值对的示例字符串,希望从中提取所有键值对。以下是我的代码片段:

import re

sample_string = r"""
$key1 = 'val1';
$key2 = 'val2';
$key3 = 'val3';
$key4 = 'val4';

$key5 = (
  {
    key1   => 'val1',
    key2   => 'val2',
  },
);

"""

reg_exp = re.compile(r"\$(.+?)\s*=\s*(.*?);")
for match in reg_exp.finditer(sample_string, re.MULTILINE | re.DOTALL):
    ss = match.groups()
    print(ss)

但这段代码仅识别出部分键值对:

('key3', "'val3'")
('key4', "'val4'")

请问我遗漏了什么?


问题分析与解决

1. flags参数传递错误

你在finditer中把re.MULTILINE | re.DOTALL作为第二个参数传入,但re.finditer的第二个参数是匹配的起始位置pos,并非flags参数。这导致正则从字符串的第24个字符(re.MULTILINE=8,re.DOTALL=16,两者相加为24)开始匹配,直接跳过了前两个$key1和$key2,所以只捕获到了后面的$key3和$key4。

正确的做法是在编译正则时添加flags,或者在finditer中使用关键字参数flags=...。

2. 正则表达式的匹配逻辑缺陷

原正则\$(.+?)\s*=\s*(.*?);的非贪婪匹配.*?在开启re.DOTALL后,会在遇到第一个分号时停止匹配,无法正确捕获$key5这种多行嵌套结构的完整值。

修正后的代码

import re

sample_string = r"""
$key1 = 'val1';
$key2 = 'val2';
$key3 = 'val3';
$key4 = 'val4';

$key5 = (
  {
    key1   => 'val1',
    key2   => 'val2',
  },
);

"""

# 编译时指定flags,调整正则以匹配多行值
reg_exp = re.compile(r"\$(\w+)\s*=\s*([\s\S]*?);", re.DOTALL)
for match in reg_exp.finditer(sample_string):
    print(match.groups())

如果要避免值内部的分号干扰(比如值本身包含分号的场景),可以用更严谨的逻辑(Python原生正则不支持平衡组,这里用负向预查适配示例结构):

reg_exp = re.compile(r"\$(\w+)\s*=\s*(.*?)(?<!,);", re.DOTALL)

修正后的输出

('key1', "'val1'")
('key2', "'val2'")
('key3', "'val3'")
('key4', "'val4'")
('key5', "(
  {
    key1   => 'val1',
    key2   => 'val2',
  },
)")

内容的提问来源于stack exchange,提问作者ManiAm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:37:02