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']
比赛的"size ="部分消失了.(但肯定会在搜索中使用,否则会有更多结果).我究竟做错了什么?
Vol*_*ity 35
您遇到的问题是,如果re.findall尝试匹配的正则表达式捕获组(即括号中包含的正则表达式部分),那么它是返回的组,而不是匹配的字符串.
解决此问题的一种方法是使用非捕获组(前缀为?:).
>>> import re
>>> s = 'size=50;size=51;'
>>> re.findall('size=(?:50|51);', s)
['size=50;', 'size=51;']
如果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;']
再次,从文档:
(?:...)常规括号的非捕获版本.匹配括号内的正则表达式,但在执行匹配或稍后在模式中引用后,无法检索组匹配的子字符串.
小智 5
在某些情况下,非捕获组不合适,例如使用正则表达式检测重复的单词(来自python 文档的示例)
r'(\b\w+)\s+\1'
在这种情况下,要获得整场比赛,可以使用
[groups[0] for groups in re.findall(r'((\b\w+)\s+\2)', text)]
请注意,\1已更改为\2.