【发布时间】:2012-04-18 21:52:28
【问题描述】:
我正在尝试使用从http://daringfireball.net/2010/07/improved_regex_for_matching_urls 获得的匹配正则表达式的 URL
(?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 中进行 % 编码,但不是将处理几乎所有内容,并且不会导致正则表达式匹配器呈指数增长。
-
你试过 Rubular 吗?它下面有一个方便的备忘单,您可以添加各种测试表达式以确保它有效。 (P.S. 我知道这是针对 js 的,但这仍然是一个方便的资源。)rubular.com
标签: javascript regex backtracking