这是Python regex中的bug吗?

2024-04-25 18:01:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我认为我对RegEx已经足够好了,我几乎可以阅读任何一个,但是这个简单的(Python)却让我困惑不解。www.regexpal.com网站给出了与iPython不同的结果。在

data = 'four year entrepreneurial program. Students develop and run a business, gain much needed ...'

m = re.compile('entrepreneur|business\s(plan|model)')

m.findall(data)

给出['']

这怎么可能是对的?如果我用parens包装整个东西,效果会更好,但仍然返回一个空字符串作为匹配:

^{pr2}$

给出[('entrepreneur', '')]

就像我说的,第一个是有效的www.regexpal.com。我还用Python(不是iPython)测试了它,结果也失败了。在


Tags: comdata网站wwwipythonbusinessprogramyear
3条回答

这就是捕获组与findall一起工作的方式。在

re.findall(pattern, string, flags=0)

Return all non-overlapping matches of pattern in string, as a list of strings. The string is scanned left-to-right, and matches are returned in the order found. If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result unless they touch the beginning of another match.

在你的交替的右手边有一个捕捉组,但是交替的左手边与你的字符串匹配。在

entrepreneur|business\s(plan|model)

Regular expression visualization

Debuggex Demo

因此,组是空的,因为左边匹配,这就是findall给你的。在

要修复此问题,请使您的组不捕获:

^{pr2}$

现在,没有组,因此findall返回与主表达式匹配的值。在

findall收集组的值。它不返回整个匹配的子字符串。你的模式

entrepreneur|business\s(plan|model)

循环遍历数据字符串,直到找到匹配项。一旦找到匹配项(这里是entrepreneurial program...),它就会停止并捕获第一个组的值(它是空的)。然后它继续运行,但找不到任何匹配项。所以最终的结果是一个包含一个空字符串的列表。在

要观察与regexpal类似的行为,请将整个表达式括起来,并使其他组可选:

^{pr2}$

问题是括号。它们创建一个捕捉组,这个组与示例字符串不匹配(模式的ungroup entrepreneur部分匹配)。re.findall如果模式中有任何组,则返回捕获组结果的a元组,因此得到一个空字符串的原因。在代码的第二个版本中,有两个组,第一个组覆盖整个模式,而第二个组只覆盖plan|model部分(不匹配)。在

如果使用非捕获组((?:X))进行plan|model替换,则可能会得到预期的结果(文本"entrepreneur"),因为如果没有捕获组,re.findall将返回整个匹配的文本。在

尝试:"entrepreneur|business\s(?:plan|model)"

相关问题 更多 >