re.findall没有返回完全匹配?

Ben*_* S. 18 python regex python-2.7

我有一个包含一堆字符串的文件,例如"size = XXX;".我想,第一次Python的re模块和我有点通过以下行为迷惑:如果我使用的管道"或"正则表达式,我只看到了比赛的那一点回来.例如:

>>> myfile = open('testfile.txt','r').read()
>>> print re.findall('size=50;',myfile)
['size=50;', 'size=50;', 'size=50;', 'size=50;']
>>> print re.findall('size=51;',myfile)
['size=51;', 'size=51;', 'size=51;']
>>> print re.findall('size=(50|51);',myfile)
['51', '51', '51', '50', '50', '50', '50']
>>> print re.findall(r'size=(50|51);',myfile)
['51', '51', '51', '50', '50', '50', '50']
Run Code Online (Sandbox Code Playgroud)

比赛的"size ="部分消失了.(但肯定会在搜索中使用,否则会有更多结果).我究竟做错了什么?

Vol*_*ity 35

您遇到的问题是,如果re.findall尝试匹配的正则表达式捕获组(即括号中包含的正则表达式部分),那么它是返回的组,而不是匹配的字符串.

解决此问题的一种方法是使用非捕获组(前缀为?:).

>>> import re
>>> s = 'size=50;size=51;'
>>> re.findall('size=(?:50|51);', s)
['size=50;', 'size=51;']
Run Code Online (Sandbox Code Playgroud)

如果re.findall尝试匹配的正则表达式不捕获任何内容,则返回整个匹配的字符串.

虽然在这种特殊情况下使用字符类可能是最简单的选项,但非捕获组提供了更通用的解决方案.


Zer*_*eus 10

当正则表达式包含括号时,它们将其内容捕获到组,将行为更改findall()为仅返回这些组.以下是文档中的相关部分:

(...)

匹配括号内的正则表达式,并指示组的开始和结束; 可以在执行匹配后检索组的内容,并且可以在字符串中稍后与\number特殊序列匹配,如下所述.要匹配的文字'('')'使用\(\),或将它们括字符类中:[(] [)].

要避免此行为,您可以使用非捕获组:

>>> print re.findall(r'size=(?:50|51);',myfile)
['size=51;', 'size=51;', 'size=51;', 'size=50;', 'size=50;', 'size=50;', 'size=50;']
Run Code Online (Sandbox Code Playgroud)

再次,从文档:

(?:...)

常规括号的非捕获版本.匹配括号内的正则表达式,但在执行匹配或稍后在模式中引用后,无法检索组匹配的子字符串.


小智 5

在某些情况下,非捕获组不合适,例如使用正则表达式检测重复的单词(来自python 文档的示例)

r'(\b\w+)\s+\1'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,要获得整场比赛,可以使用

[groups[0] for groups in re.findall(r'((\b\w+)\s+\2)', text)]
Run Code Online (Sandbox Code Playgroud)

请注意,\1已更改为\2.