我的python版本是2.7.6
我知道 +?+ 的非贪婪版本。
这样 re.findall('(ab)+?', 'abab') 将尽可能少地匹配 ab
结果 ['ab', 'ab'] 因此是有道理的。

但是当谈到贪婪版本匹配 re.findall('(ab)+', 'abab') 时,它​​让我感到困惑。
我认为贪婪的版本应该尽可能多地匹配 ab
因此我将得到 ['abab'] 作为结果。
但是我得到了 ['ab'] !

在 re.findall() 的帮助信息中,它说:

Return a list of all non-overlapping matches in the string.
If one or more groups are present in the pattern, return a
list of groups; this will be a list of tuples if the pattern
has more than one group.

Empty matches are included in the result.

这里我有两个组,整个 RE 的默认 group0 ,以及我指定的 (ab)group1

于是我做了以下调查:
In [21]: ng = re.search('(ab)+?', 'abab')

In [22]: g = re.search('(ab)+', 'abab')

In [23]: ng.group(0)
Out[23]: 'ab'

In [24]: ng.group(1)
Out[24]: 'ab'

In [25]: g.group(0)
Out[25]: 'abab'

In [26]: g.group(1)
Out[26]: 'ab'

很明显,re 模块将 'abab' 匹配为 group0,将 'ab' 匹配为 group1 以进行贪婪搜索。
但是为什么我在执行 ['ab'] 操作时得到的是 ['abab', 'ab'] 而不是 findall() 呢?
因为 'abab' 包含 ab 所以它们是重叠的,而 findall() 在这种情况下只返回最后一个匹配?

带着这个问题,我做了以下测试:
In [30]: g = re.findall('[A-z](ab)+', 'ababdab')

In [31]: g
Out[31]: ['ab', 'ab']

In [32]: dg = re.search('[A-z](ab)+', 'ababdab')

In [33]: dg.groups()
Out[33]: ('ab',)

In [34]: dg.group()
Out[34]: 'bab'

现在我完全失去理智了。
findall 在这里是如何工作的?
为什么???

最佳答案

这里有一个微妙之处 - 在杰瑞的回答中有所涉及,但没有明确说明。

您希望 re.findall('(ab)+', 'abab') 告诉您整个正则表达式匹配的隐式“组 0”和括号中的“组 1”。 这不是它的工作原理。 如果有捕获括号, findall 的列表只包含捕获括号的组。观察:

>>> re.findall('(?:ab)+', 'abab') # no capture, reports group 0
['abab']
>>> re.findall('(ab)+', 'abab')   # one capture, reports _only_ group 1
['ab']
>>> re.findall('((ab)+)', 'abab') # two captures, reports both groups 1 and 2
[('abab', 'ab')]                  # (but still not group 0)

文档可以更清楚地说明这一点。它假定您了解“第 0 组”并不真正算作一个组。但这就是 RE 库几十年来的工作方式。

关于python - 为什么 re.findall ('(ab)+' , 'abab' ) 返回 ['ab' ]= 同时 re.findall ('(ab)+?' , 'abab' ) 返回 ['ab' , 'ab' ]?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29430909/

10-12 22:51