>>> 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']
>>>
>>> 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']
>>>
findall
默认情况下不会产生重叠的匹配结果。但是,这个表达式可以:
>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']
这里的(?=...)
是一种前向断言:
(?=...)
匹配如果...
紧随其后,但不会消耗字符串。这被称为前向断言。例如,Isaac (?=Asimov)
只会匹配'Isaac '
如果它后面跟着'Asimov'
。
>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
除了零长度断言外,输入中的字符始终会在匹配过程中被消耗。 如果您需要捕获输入字符串中特定字符多次出现的情况,您将需要在正则表达式中使用零长度断言。
有几种零长度断言(例如 ^
(输入/行开头), $
(输入/行结尾), \ b
(单词边界)),但是环视( (? <=)
正向后查找和 (? =)
正向前查找)是唯一一种可以从输入中捕获重叠文本的方法。负向环视( (? 负向后查找,
(?!)
负向前查找)在这里不太有用:如果它们为真,则内部捕获失败;如果它们为假,则匹配失败。这些断言是零长度的(如前所述),这意味着它们会在不消耗输入字符串中的字符的情况下进行断言。 如果断言通过,它们实际上将匹配空字符串。
应用上述知识,适用于您情况的正则表达式将是:
(?=(\w\w))
虽然我不是正则表达式专家,但我想回答一个类似的问题。
如果你想在前瞻中使用捕获组:
示例正则表达式:(\d)(?=.\1)
字符串:5252
这将匹配第一个5和第一个2
(\d)
用于创建一个捕获组,(?=\d\1)
用于匹配任何数字后跟捕获组1而不消耗字符串,从而允许重叠。