为什么这个正则表达式会超时?

时间:2014-09-04 20:11:00

标签: ruby regex

这可能不是Stackoverflow的理想问题,对不起,如果我真的违反了指南(比如#34; Too本地化"。但这是一个非常有趣的问题:

我有以下Regex(更简单的URL匹配版本):

\A(http(s)?:\/\/)?(([\da-z\.-]+)\.([a-z]{2,6})(\.([a-z]{2,6}))?([\/\w \.-]*)*\/?)\z

现在如果我测试这个字符串(因为特殊字符而不匹配):

http://t3n.de/news/nokia-lumia-930-test-560264/?utm_source=feedburner+t3n+News+12.000er&utm_medium=feed&utm_campaign=Feed%3A+aktuell%2Ffeeds%2Frss+%28t3n+News%29

像这样(只是为了确保我没有犯明显的错误):

str = 'http://t3n.de/news/nokia-lumia-930-test-560264/?utm_source=feedburner+t3n+News+12.000er&utm_medium=feed&utm_campaign=Feed%3A+aktuell%2Ffeeds%2Frss+%28t3n+News%29'
str.match /\A(http(s)?:\/\/)?(([\da-z\.-]+)\.([a-z]{2,6})(\.([a-z]{2,6}))?([\/\w \.-]*)*\/?)\z/i

该命令永远运行。由于字符串不匹配,它不应该返回nil吗?我使用最新版本的ruby,但这也发生在Rubular上:http://rubular.com/r/2ajABaqmTE

jarvis:~ rudolf$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

任何可能导致此问题的想法?我发现了一个Ruby错误或者我错过了什么?

2 个答案:

答案 0 :(得分:3)

在正则表达式中,有以下内容:

([\/\w \.-]*)*

导致正则表达式引擎创建了许多可能回溯到的状态。您可以安全地删除最后一个*

([\/\w \.-]*)

答案 1 :(得分:1)

我看到它的方式,此部分*中的第二个([\/\w \.-]*)*是多余的,会导致大量的回溯。删除它,它工作正常:([\/\w \.-]*)

你有很多捕捉群体,如果你不打算使用它们,你可能也想删除它们,但这不会产生那么大的影响。