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

Dal*_*ers 12 python regex

我有代码:

import re
sequence="aabbaa"
rexp=re.compile("(aa|bb)+")
rexp.findall(sequence)
Run Code Online (Sandbox Code Playgroud)

这回来了 ['aa']

如果我们有

import re
sequence="aabbaa"
rexp=re.compile("(aa|cc)+")
rexp.findall(sequence)
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

ovg*_*vin 10

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

rexp=re.compile("(aa|bb)+")
Run Code Online (Sandbox Code Playgroud)

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

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

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

当你组建一个小组时,它首先被数学aa,然后bbaa被数学(因为+量词).所以这个小组aa最终坚持了下来.并findall在列表中返回此值['aa'](因为aabbaa整个表达式只有一个匹配项,列表只包含一个aa保存在组中的元素).

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

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

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

在问题的最后,您将显示所需的输出.这是通过寻找aa或来实现的bb.不需要量词(+*).就像Inbar Rose的回答一样:

>>> rexp=re.compile("aa|bb")
>>> rexp.findall(sequence)
['aa', 'bb', 'aa']
Run Code Online (Sandbox Code Playgroud)


Inb*_*ose 7

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

regex = re.compile("(aa|bb)+")
Run Code Online (Sandbox Code Playgroud)

要创建一个正则表达式,这将寻找aabb然后会尝试寻找是否有更多的aa还是bb在那之后,它会继续寻找aabb直至它不找到.因为您希望您的捕获组仅返回aa或者bb您只获得最后捕获/找到的组.

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

我希望这能解释你在做什么.这是预期的.获取任何一组aabb你需要删除+正在告诉正则表达式在返回匹配之前寻找多个组.只有正则表达式返回每个匹配aabb...

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

regex = re.compile("(aa|bb)")
Run Code Online (Sandbox Code Playgroud)

干杯.