2013-01-02 73 views
9
import re 
str='abc defg' 
m1 = re.match(".*(def)?",str) 
m2 = re.match(".*(def)",str) 
print (m1.group(1),m2.group(1)) 

上面的輸出是:Python正則表達式問號運算符不工作?

(無, '高清')

這是怎麼回事?即使使用非貪婪的重複操作符,可選捕獲組(def)?也不匹配。

回答

13

這裏的時候正則表達式引擎嘗試匹配.*(def)abc defg會發生什麼:

  • 首先,發動機開始嘗試正則表達式在字符串的開頭相匹配。
  • 貪婪的子模式.*最初嘗試匹配儘可能多的次數,匹配整個字符串。
  • 由於這會導致匹配的其餘部分失敗,因此正則表達式引擎會回溯到找到與(def)相匹配的方式,而.*僅匹配abc 時會發生這種情況。

但是,如果我們改變了正則表達式來.*(def)?,會發生以下情況相反:

  • 首先,正則表達式引擎再次啓動在字符串的開頭。
  • 接下來,它再次嘗試匹配.*儘可能多次,以匹配整個字符串。
  • 但是在這一點上,因爲正則表達式的所有其餘部分是可選的,所以它找到了整個正則表達式的匹配!由於(def)?是貪婪的,引擎寧願匹配它,如果可能的話,但它不會回溯到早些時候的子模式,只是爲了看看它是否可以。相反,它只會讓.*吞噬整個字符串,而不會爲(def)?留下任何內容。

同樣的事情也發生與.*?(def).*?(def)?

  • 同樣,發動機開始在字符串的開頭。
  • 非實質性子模式.*?儘可能匹配幾個次,即根本不匹配。
  • 那時,(def)不能匹配,但(def)?可以。因此,對於(def),正則表達式引擎必須返回並考慮.*?的較長匹配,直到它找到一個讓整個模式匹配的匹配,而對於(def)?則不必這樣做,所以它不會。

有關更多信息,請參閱"Combining RE Pieces" section of the Perl regular expressions manual(它與Python的「Perl兼容」正則表達式的行爲相匹配)。

+0

對不起,我沒有接受你的答案,直到現在。我是新來的論壇,並不確定事情。並感謝您的全面解釋。實際上我之前編寫過一個正則表達式引擎,所以我應該能夠弄清楚這一點。 – erjoalgo