Python re.findall()没有按预期工作

时间:2012-10-21 15:50:25

标签: python regex

我有代码:

import re
sequence="aabbaa"
rexp=re.compile("(aa|bb)+")
rexp.findall(sequence)

这会返回['aa']

如果我们有

import re
sequence="aabbaa"
rexp=re.compile("(aa|cc)+")
rexp.findall(sequence)

我们得到['aa','aa']

为什么会有差异,为什么(第一个)我们没有得到['aa','bb','aa']

谢谢!

4 个答案:

答案 0 :(得分:9)

不受欢迎的行为归结为你制定规则表达的方式:

rexp=re.compile("(aa|bb)+")

圆括号(aa|bb)组成一个组。

如果我们查看docs of findall,我们会看到:

  

返回字符串中所有非重叠的模式匹配,作为列表   字符串。从左到右扫描字符串,并返回匹配项   按顺序找到。 如果某个或更多的群组在,则   返回群组列表;如果模式,这将是一个元组列表   有不止一个团体。结果中包含空匹配   除非他们触及另一场比赛的开始。**

当你组建一个小组时,它首先计算aa,然后计算bb,然后再计算aa(因为+量词)。所以这个小组最后持有aa。并且findall会在列表['aa']中返回此值(因为整个表达式只有一个匹配aabbaa,该列表只包含一个元素aa,该元素保存在基)。

从您提供的代码中,您似乎想要这样做:

>>> rexp=re.compile("(?:aa|bb)+")
>>> rexp.findall(sequence)
['aabbaa']

(?: ...)不会创建任何组,因此findall会返回整个表达式的匹配。

在问题的最后,您会显示所需的输出。只需查找aabb即可实现此目的。不需要量词(+*)。就像Inbar Rose的回答一样:

>>> rexp=re.compile("aa|bb")
>>> rexp.findall(sequence)
['aa', 'bb', 'aa']

答案 1 :(得分:6)

让我解释一下你在做什么:

regex = re.compile("(aa|bb)+")

您正在创建一个正在查找aabb的正则表达式,然后会尝试查找之后是否还有aabb,并且继续寻找aabb,直到它找不到为止。由于您希望捕获组仅返回aabb,因此您只能获得最后捕获/找到的组。

但是,如果您有这样的字符串:aaxaabbxaa,您将获得aa,bb,aa,因为您首先查看字符串并找到aa,然后您会查找更多字符串,并且仅查找一个x,所以你有一组。然后你找到了另一个aa,但是你找到了bb,然后是x,所以你停下来,你的第二组是bb。然后你找到另一个aa。所以你的最终结果是aa,bb,aa

我希望这可以解释你在做什么。这是预期的。要获得aabb的任意一组,您需要删除+,这会告诉正则表达式在返回匹配项之前寻找多个组。只需让正则表达式返回aabb ...

的每个匹配项

所以你的正则表达式应该是:

regex = re.compile("(aa|bb)")

欢呼声。

答案 2 :(得分:0)

你的模式

rexp=re.compile("(aa|bb)+")

匹配整个字符串aabbaa。澄清一下这个

>>> re.match(re.compile("(aa|bb)+"),"aabbaa").group(0)
'aabbaa'

此外没有其他子串匹配

>>> re.match(re.compile("(aa|bb)+"),"aabbaa").group(1)
'aa'

所以findall只会返回一个子字符串

>>> re.findall(re.compile("(aa|bb)+"),"aabbaa")
['aa']
>>> 

答案 3 :(得分:-1)

我不明白为什么你使用 + - 这意味着0或1次出现,并且通常在你想要查找带有可选包含子串的字符串时使用。

>>> re.findall(r'(aa|bb)', 'aabbaa')
['aa', 'bb', 'aa']

按预期工作