我的python版本是2.7.6
我知道+?是+的非贪婪版本。
因此re.findall('(ab)+?', 'abab')将尽可能少地匹配ab。
因此,结果['ab', 'ab']是有意义的。
但当谈到贪婪的版本match 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,以及我指定的group1 (ab)。
所以我做了以下调查:
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进行贪婪搜索。
但是为什么我在做findall()操作的时候会用['ab']而不是['abab', 'ab']呢?
因为'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在这里是如何工作的?
为什么?
发布于 2016-01-19 03:22:11
这里有一个微妙的地方-在Jerry的回答中提到了,但没有清楚地说明。
您希望re.findall('(ab)+', 'abab')告诉您整个正则表达式匹配的隐式"group 0“和圆括号的"group 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)文档可以更清楚地说明这一点。它假设您理解"group 0“并不真正算作一个组。但这就是几十年来RE库的工作方式。
发布于 2015-04-03 19:13:33
findall就像它应该工作的那样工作:
接下来,只要有重复的组,MatchObject就会返回最后捕获的组。它在docs中提到过
如果一个组匹配多次,则仅最后一个匹配为accessible:
m = re.match(r"(..)+","a1b2c3") #匹配3次。>>> m.group(1) #仅返回最后一个匹配项。'c3'
因此,这两个现象的组合给出了你正在体验的结果。
发布于 2015-04-03 19:25:36
看一看:
In [13]: re.findall('(ab)', 'ababab')
Out[13]: ['ab', 'ab', 'ab']
In [14]: re.findall('(ab)+?', 'ababab')
Out[14]: ['ab', 'ab', 'ab']
In [15]: re.findall('(ab)+', 'ababab')
Out[15]: ['ab']In[13]等同于In[14]。这两种模式都将匹配每个ab组。但是,In[15]将匹配所有ab连续重复,而不管它们的数量。
[A-z](ab)+模式意味着您希望所有以字母[A-z]开头的ab连续重复。在ababdab中匹配它的第一个组是bab:它以A-z中的b开头,然后有一个以d结尾的ab组,它开始了下一个匹配组。
In [20]: re.findall('[A-z](ab)+', 'XababXabXab')
Out[20]: ['ab', 'ab', 'ab']https://stackoverflow.com/questions/29430909
复制相似问题