2012-07-11 149 views
42
>>> 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'] 
>>> 
+2

[Lookahead](http://stackoverflow.com/questions/320448/overlapping-matches-in-regex) – 2012-07-11 10:45:10

回答

70

findall不會產生默認重疊的匹配。然而,這確實表達:

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

這裏(?=...)lookahead assertion

(?=...)比賽,如果接下來的比賽...,但不消耗任何 字符串。這被稱爲前瞻斷言。例如, Isaac (?=Asimov)只有跟在'Asimov'之後纔會匹配'Isaac '

7

除了零長度斷言之外,輸入中的字符將始終在匹配中消耗。如果你曾經想要在輸入字符串中捕獲特定字符,那麼你需要在正則表達式中使用零長度的斷言。

有幾個零長度斷言(例如^(輸入/行),$(輸入/行尾),\b(字邊界)的開始),但查找變通((?<=)正向後看和(?=)積極的預見性)是您可以從輸入中捕獲重疊文本的唯一方法。負面觀察((?<!)負面後視,(?!)負面預測)在這裏並不是很有用:如果他們聲明爲真,那麼捕獲內部失敗;如果他們斷言錯誤,那麼比賽失敗。這些斷言是零長度的(如前所述),這意味着它們將斷言而不消耗輸入字符串中的字符。如果斷言通過,它們實際上會匹配空字符串。

應用上述知識,對於你的情況下工作將是一個正則表達式:

(?=(\w\w)) 
20

可以使用new Python regex module,它支持重疊的匹配。

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