89
>>> match = re.findall(r'\w\w', 'hello')
>>> print match
['he', 'll']

由于 \w\w 表示两个字符,因此需要 'he' 和 'll'。但是为什么 'el' 和 'lo'与正则表达式匹配?

>>> match1 = re.findall(r'el', 'hello')
>>> print match1
['el']
>>>
4

4 回答 4

132

findall默认情况下不会产生重叠匹配。然而,这个表达式确实:

>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']

(?=...)是一个前瞻断言

(?=...)如果下一个匹配,则...匹配,但不消耗任何字符串。这称为前瞻断言。例如, 仅当它后面跟着. 时Isaac (?=Asimov)才会匹配。'Isaac ''Asimov'

于 2012-07-11T10:44:05.500 回答
46

您可以使用支持重叠匹配的新 Python 正则表达式模块

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
于 2013-09-23T18:54:12.637 回答
11

除了零长度断言外,输入中的字符将始终在匹配中被消耗。如果您曾经想在输入字符串中多次捕获某些字符,则需要在正则表达式中进行零长度断言。

有几个零长度断言(例如^(输入/行的开头)、$(输入/行的结尾)、\b(字边界)),但环顾四周((?<=)正向后视和(?=)正向前瞻)是唯一的方法您可以从输入中捕获重叠的文本。否定的环视((?<!)negative look-behind,(?!)negative look-ahead)在这里不是很有用:如果它们断言为真,则内部捕获失败;如果他们断言为假,则匹配失败。这些断言是零长度的(如前所述),这意味着它们将断言而不消耗输入字符串中的字符。如果断言通过,它们实际上将匹配空字符串。

应用上述知识,适用于您的案例的正则表达式将是:

(?=(\w\w))
于 2012-07-11T10:51:52.560 回答
0

我不是正则表达式专家,但我想回答我的类似问题

如果要使用具有前瞻功能的捕获组:

正则表达式示例:(\d)(?=.\1)

细绳:5252

这将匹配前 5 个和前 2 个

(\d)就是做一个捕获组,(?=\d\1)就是匹配捕获组1后面的任何数字而不消耗字符串,因此允许重叠

于 2019-02-04T15:41:01.263 回答