2014-12-07 26 views
2

假設我們有一個字符串1abcd1efg1hjk1lmn1並且想要找到1-s之間的東西。我們做的是不懂延遲正則表達式

re.findall('1.*?1','1abcd1efg1hjk1lmn1') 

,並得到兩個結果

['1abcd1', '1hjk1'] 

好,我明白了。但如果我們這樣做

re.findall('1.*?1hj','1abcd1efg1hjk1lmn1') 

爲什麼它抓住兩個間隔1而不是一個?爲什麼我們得到['1abcd1efg1hj']而不是['1efg1hj']?這不是懶惰應該做的嗎?

+3

https://regex101.com/r/vD6xF7/2點擊'正則表達式debugger',看看到底發生了什麼 – hjpotter92 2014-12-07 15:08:52

+1

正則表達式引擎從左向右解析字符串,並始終給出最左邊的結果,無論使用何種量詞。 – 2014-12-07 16:22:49

回答

4

正則表達式總是嘗試從左到右匹配輸入字符串。考慮你的'1.*?1hj'正則表達式。 1在您的正則表達式匹配第一個和下面的.*?匹配所有字符到1hj子字符串非貪婪。所以,你得到了,而不是['1efg1hj']

['1abcd1efg1hj']要獲得['1efg1hj']作爲輸出,你需要用一個否定類爲1[^1]*1hj

>>> s = "1abcd1efg1hjk1lmn1" 
>>> re.findall(r'1.*?1hj', s) 
['1abcd1efg1hj'] 
>>> re.findall(r'1[^1]*1hj', s) 
['1efg1hj'] 
+0

是的,在這種情況下,否定的階級就是要走的路。但想象一下,你的「分隔符」是多字符的,例如「123」而不是「1」。在這種情況下你會如何解決這個問題? 你不能使用'[^ ​​123]',因爲你仍然希望單個字符匹配,除非它們一起出現。 – Alphaaa 2015-10-09 10:45:05

+0

嘗試'(?:(?! 123)。)*?' – 2015-10-09 10:54:55

+0

它的作品,很好! – Alphaaa 2015-10-10 04:13:23

0
['1abcd1efg1hj'] 

你得到這個怎麼把這個滿足您的正則表達式。 1.*?1hj實質上是指從1然後開始懶洋洋地移動,直到你找到之間其次hj .The 11如果follwed通過ef這樣就不會匹配,但.會消耗all.You沒有得到['1efg1hj']怎麼把這個字符串已經通過姆第一消費匹配。使用前瞻可以看到既滿足條件。請參閱演示。

等你拿這兩個對手在先行不消耗串,

https://regex101.com/r/aQ3zJ3/5