14

我有代码:

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

4 回答 4

11

不需要的行为归结为您制定正则表达式的方式:

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

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

如果我们查看findall 的文档,我们会看到:

返回字符串中模式的所有非重叠匹配,作为字符串列表。从左到右扫描字符串,并按找到的顺序返回匹配项。如果模式中存在一个或多个组, 则返回组列表;如果模式有多个组,这将是一个元组列表。空匹配包含在结果中,除非它们触及另一匹配的开头。**

当你组成一个组时,它首先计算aa,然后bb,然后aa再计算(因为+量词)。所以这个组aa最终成立。并findall在列表中返回此值(由于整个表达式['aa']只有一个匹配项,因此列表仅包含一个保存在组中的元素)。aabbaaaa

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

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

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

在您的问题结束时,您会显示所需的输出。这是通过寻找aaor来实现的bb。不需要量词 (+*)。按照 Inbar Rose 的回答中的方式进行操作:

>>> rexp=re.compile("aa|bb")
>>> rexp.findall(sequence)
['aa', 'bb', 'aa']
于 2012-10-21T16:12:44.873 回答
10

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

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

您正在创建一个正则表达式,它将查找aaorbb然后将尝试查找是否有更多aaorbb之后,它将继续查找aaorbb直到找不到。因为你希望你的捕获组只返回aaorbb然后你只得到最后一个捕获/找到的组。

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

我希望这能解释你在做什么。正如预期的那样。要获得任何组,aa或者bb您需要删除+告诉正则表达式在返回匹配之前寻找多个组的组。并且只需让正则表达式返回aaor bb...

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

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

干杯。

于 2012-10-21T16:12:21.210 回答
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']
>>> 
于 2012-10-21T16:35:46.763 回答
-1

I do not understand why you use + - it means 0 or 1 occurrence, and is usually used when you want find string with optional inclusion of substring.

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

work as expected

于 2012-10-21T15:58:42.100 回答