我有一个包含一堆字符串的文件,例如“size = XXX;”。我是第一次尝试python的re模块,并且由于以下行为而有点神秘:如果我在正则表达式中使用'或'管道,我只会看到匹配的位返回。 E.g:
>>> 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 =”部分消失了。 (但肯定会在搜索中使用,否则会有更多结果)。我做错了什么?
答案 0 :(得分:28)
你遇到的问题是,如果re.findall
尝试匹配的正则表达式捕获组(即括号中包含的正则表达式部分),那么它是返回的组,而不是匹配的组字符串。
解决此问题的一种方法是使用非捕获组(前缀为?:
)。
>>> import re
>>> s = 'size=50;size=51;'
>>> re.findall('size=(?:50|51);', s)
['size=50;', 'size=51;']
如果re.findall
尝试匹配的正则表达式没有捕获任何内容,则返回整个匹配的字符串。
虽然在这种特殊情况下使用character classes可能是最简单的选项,但非捕获组提供了更通用的解决方案。
答案 1 :(得分:8)
当正则表达式包含括号时,它们将其内容捕获到组中,将findall()
的行为更改为仅返回这些组。以下是the docs的相关部分:
(...)
匹配括号内的正则表达式, 并指示组的开始和结束;一组的内容 可以在执行匹配后检索,并且可以匹配 稍后在具有
\number
特殊序列的字符串中进行描述 下面。要匹配文字'('
或')'
,请使用\(
或\)
,或将其括起来 在角色类中:[(] [)]
。
要避免此行为,您可以使用非捕获组:
>>> print re.findall(r'size=(?:50|51);',myfile)
['size=51;', 'size=51;', 'size=51;', 'size=50;', 'size=50;', 'size=50;', 'size=50;']
再次,来自文档:
(?:...)
常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配后或在模式中稍后引用时,无法检索组匹配的子字符串。
答案 2 :(得分:2)
'size=(50|51);'
表示您正在寻找size=50
或size=51
但只匹配50
或51
部分(请注意括号),因此它不会返回sign=
。
如果您想要返回sign=
,则可以执行以下操作:
re.findall('(size=50|size=51);',myfile)
答案 3 :(得分:1)
我认为你想要的是使用[]而不是()。 []表示字符集,而()表示组匹配。尝试这样的事情:
print re.findall('size=5[01];', myfile)
答案 4 :(得分:0)
在某些情况下,非捕获组不合适,例如使用正则表达式检测重复的单词(例如来自python docs)
r'(\b\w+)\s+\1'
在这种情况下获得完整匹配可以使用
[groups[0] for groups in re.findall(r'((\b\w+)\s+\2)', text)]
请注意,\1
已更改为\2
。
答案 5 :(得分:0)
这是一个干净的解决方案:https://www.ocpsoft.org/tutorials/regular-expressions/or-in-regex/ 如果网站死在这里是示例(尝试在 regex101.com 上):
正则表达式:
^I like (dogs|penguins), but not (lions|tigers).$
尝试:
我喜欢狗,但不喜欢狮子。
我喜欢狗,但不喜欢老虎。
我喜欢企鹅,但不喜欢狮子。
我喜欢企鹅,但不喜欢老虎。
匹配 1 全场 2-29 我喜欢狗,但不喜欢狮子。 第 1 组。 9-13 只狗 第 2 组。 23-28 只狮子 ...
但使用正则表达式:
^I like (?:dogs|penguins), but not (?:lions|tigers).$
第一场
全场 2-29 我喜欢狗,但不喜欢狮子。
第 2 场比赛
全场 30-58 我喜欢狗,但不喜欢老虎。
...