2017-05-18 61 views
-1

正則表達式:爲什麼這個python regexp掛起?

^(\w+,?\s?)+(?=:): hi hey\?$ 

輸入:

Aaaaaaaaa, bbbbbbbb, cccccccc, dddddddddd, eeeeeeeee: hi? 

輸出:掛起

代碼

reg = re.compile('^(\w+,?\s?)+(?=:): hi hey\?$') 
print reg.search('Aaaaaaaaa, bbbbbbbb, cccccccc, dddddddddd, eeeeeeeee: hi?') 

期望的行爲:發現具有以下模式串

輸入
[comma_and_(optionally)space_separated_values][colon][question] 

實施例,不應該相匹配:

  • : qqq?(沒有值)
  • aa: qqq?(只有一個值)
  • aa, bb: qqq(無問題點)
  • aa, : qqq?(壞值格式)
  • aa, bb, cc:?(無問題)
  • , bb, cc: qqq?(壞值格式)的輸入

實施例應當匹配:

  • aa, bb: qq?
  • aa, b, c,d,e,f, g, h: qq?
  • aa, bb, cc: qq ee ff gggg hhhh?
+2

雖然'(?= :)'先行是多餘這裏,主要的問題是,'(\ w +,?\ s?)+'包含一個強制性的' \ w +',其餘是可選的。這是導致災難性回溯的典型模式。使用['^ \ w +(?:,\ s * \ w +)*:。* \?$'](https://regex101.com/r/EhtNUw/2)。 –

+0

我不是很流利的正則表達式,但[this](http://stackoverflow.com/questions/8316284/why-regex-ismatch-hangs)可能與 – Wondercricket

+1

有關係。您可以使用:['^ \ w +(? :\ s *,\ s * \ w +)* \ s *:\ s *([^?] + \?)'](https://regex101.com/r/JqnwnT/2) – anubhava

回答

1

它掛,因爲這(\w+)+場景。
I.e. 太複雜失敗。
工作正常,如果匹配,失敗時炸燬。

This (\w,?\s?)+(\w+,?\s?)+完全相同,但不會掛起。

因此,將其更改爲此^(\w,?\s?)+(?=:): hi hey\?$並解決問題。

作爲獎勵,這^(\w,?\s?)+: hi hey\?$是相同的。

此外,您可以用.*?\?$代替您的文字hi hey\?$
如果預期爲變量字面值。


Error: Target Operation .. 

The complexity of matching the regular 
expression exceeded predefined bounds. 
Try refactoring the regular expression 
to make each choice made by the state 
machine unambiguous. This exception is 
thrown to prevent "eternal" matches that 
take an indefinite period time to 
locate. 

編輯:

注意,有總是嵌套量詞一個潛在的問題。
I.e.那些貪婪和開放式的,如(b +*

這幾乎可以通過刪除一個內部的巢(如在示例b+)解決。
通過使它不被量化,我們可以稱之爲僞錨。

也就是說,它應該是該組中的第一個並且是一個未定量的必需字符。

這會迫使發動機回原點字符再次檢查它。
如果沒有量化,立即放棄,甚至不會看
表達式的其餘部分。
因此,它經過字符串中的該位置以找到下一個字面值b

基本上這是什麼回溯治療是全部。

鑑於回溯陷阱,我們可以做出解決方案來獲得所需的匹配。

^\s*(\w+\s*(?:[,\s]\s*\w+\s*)+)\s*:\s*([^:]*?\w[^:]*?)\s*\?\s*$

Formatted

^       # BOS 
\s*       # Wsp trim 
(       # (1 start), Values - minimum of 2 required 
     \w+ \s*      # First word 
     (?: [,\s] \s* \w+ \s*)+  # One or more space or comma seperated 
            # word value's 
)        # (1 end) 
\s*       # Wsp trim 
:        # Colon 
\s*       # Wsp trim 
(       # (2 start), Question - 
     [^:]*?      # Not a colon 
     \w       # At least a word char 
     [^:]*?      # Not a colon 
)        # (2 end) 
\s*       # Wsp trim 
\?       # '?' 
\s*       # Wsp trim 
$        # EOS 
+0

聽起來很有趣。原來的掛起,但與changings沒有問題了 – am2

+1

@ am2 - 有道理。很少有關於正確解釋失控回溯的解釋。所有正則表達式的原因大多是不同的,微妙的部分互相影響。你會得到與這些形式相同的問題'(\ w *)*','(\ w +)*','(\ w *)+','(\ w +)+'。哪些實際上很常見。但是與其他部分一起,它爆炸了。治療(回退)就像在這個答案中一樣。總是測試(強制)所有正則表達式的失敗。 – sln

+0

你的回答很明確。我不知道誰低估了你,也不知道爲什麼。我upvoted並接受 – nonsensei