我有代码:
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']
?
谢谢!
答案 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
会返回整个表达式的匹配。
在问题的最后,您会显示所需的输出。只需查找aa
或bb
即可实现此目的。不需要量词(+
或*
)。就像Inbar Rose的回答一样:
>>> rexp=re.compile("aa|bb")
>>> rexp.findall(sequence)
['aa', 'bb', 'aa']
答案 1 :(得分:6)
让我解释一下你在做什么:
regex = re.compile("(aa|bb)+")
您正在创建一个正在查找aa
或bb
的正则表达式,然后会尝试查找之后是否还有aa
或bb
,并且继续寻找aa
或bb
,直到它找不到为止。由于您希望捕获组仅返回aa
或bb
,因此您只能获得最后捕获/找到的组。
但是,如果您有这样的字符串:aaxaabbxaa
,您将获得aa,bb,aa
,因为您首先查看字符串并找到aa
,然后您会查找更多字符串,并且仅查找一个x
,所以你有一组。然后你找到了另一个aa
,但是你找到了bb
,然后是x
,所以你停下来,你的第二组是bb
。然后你找到另一个aa
。所以你的最终结果是aa,bb,aa
我希望这可以解释你在做什么。这是预期的。要获得aa
或bb
的任意一组,您需要删除+
,这会告诉正则表达式在返回匹配项之前寻找多个组。只需让正则表达式返回aa
或bb
...
所以你的正则表达式应该是:
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']
按预期工作