我的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/