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

时间:2013-08-25 03:31:16

标签: python regex python-2.7

我有一个包含一堆字符串的文件,例如“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 =”部分消失了。 (但肯定会在搜索中使用,否则会有更多结果)。我做错了什么?

6 个答案:

答案 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=50size=51但只匹配5051部分(请注意括号),因此它不会返回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 我喜欢狗,但不喜欢老虎。 ...