我試圖用一個URL匹配的正則表達式,我從http://daringfireball.net/2010/07/improved_regex_for_matching_urls如何讓這個正則表達式不會導致「災難性回溯」?
(?xi)
\b
( # Capture 1: entire matched URL
(?:
https?:// # http or https protocol
| # or
www\d{0,3}[.] # "www.", "www1.", "www2." … "www999."
| # or
[a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash
)
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
(?: # End with:
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
| # or
[^\s`!()\[\]{};:'".,<>?«»「」‘’] # not a space or one of these punct chars
)
)
了基於答案another question,似乎有導致此正則表達式來backtrack catastrophically箱子。例如:
var re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»「」‘’]))/i;
re.test("http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA)")
...可能需要很長的時間來執行(例如,在Chrome)
在我看來,問題在於這部分代碼:
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
...這似乎是大致相當於(.+|\((.+|(\(.+\)))*\))+
,它看起來像它包含(.+)+
有沒有變化我可以作出這樣會避免?
真的,你應該扔掉這個正則表達式,並提出一個你需要的東西。我還沒有看到一個應用程序,既蓬鬆,足以使用正則表達式進行URL解析(而不是真正的解析器),並且嚴重到需要處理URL中的嵌套圓括號。從「https?://」開始,結束於第一個字符,該字符應該在合適的URL中編碼,但不會處理幾乎所有內容,並且不會導致正則表達式匹配器呈指數式增長。 – 2012-04-18 22:28:17
你嘗試過Rubular嗎?它下面有一個方便的備忘單,您可以添加各種測試表達式,以確保其正常工作。 (P.S.我知道這是爲js,但這仍然是一個方便的資源。)http://rubular.com/ – Edwin 2012-04-18 22:28:37