如何找到与正则表达式重叠的匹配?

时间:2012-07-11 10:39:17

标签: python regex overlapping

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

因为\ w \ w表示两个字符,'他'和'll'是预期的。但为什么'el'和'lo'匹配正则表达式?

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

4 个答案:

答案 0 :(得分:83)

默认情况下,

findall不会产生重叠匹配。但是这个表达式确实如此:

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

此处(?=...)lookahead assertion

  

(?=...)匹配,如果...匹配下一个,但不消费任何   串。这称为先行断言。例如,   Isaac (?=Asimov)仅在'Isaac '后跟'Asimov'匹配。

答案 1 :(得分:29)

您可以使用支持重叠匹配的new Python regex module

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']

答案 2 :(得分:10)

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

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

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

(?=(\w\w))

答案 3 :(得分:0)

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

如果要与前瞻性一起使用捕获组:

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

字符串:5252

这将与前5个以及前2个匹配

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