【问题标题】:URL Regex strange behaviourURL 正则表达式奇怪的行为
【发布时间】:2015-04-15 12:50:36
【问题描述】:

我有一个用于用 PHP 识别 URL 的正则表达式,效果很好:

~(?i)\b(?!.*?\<<)(?!.*?\.onion)((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|ftp://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’]))~

除非这会破坏它,否则会导致灾难性的回溯:

http://google.com(JavaScript_Add-on)

有趣的是,这可以通过删除括号、下划线或连字符来避免:

http://google.comJavaScript_Add-on //This is a match

http://google.com(JavaScriptAdd-on) //This is a match

http://google.com(JavaScript_Addon) //This is a match

或者去掉最后一个字母'n':

http://google.com(JavaScript_Add-o) //This is a match

或删除“添加”一词:

http://google.com(JavaScript_-on) //This is a match

有谁知道这里发生了什么以及如何解决这个问题?

【问题讨论】:

  • 括号和下划线不是有效的域名字符:因此它们都不是有效的 URL。
  • 请在regex101.com/r/cI5eT2/2查看您修改后的正则表达式。只需将?(?:[^\s()&lt;&gt;]+|\(([^\s()&lt;&gt;]+|(\([^\s()&lt;&gt;]+\)))*\))+? 相加即可节省大量计算资源。我还在下一个非捕获组中添加了?。答案:使用 lazy 匹配。

标签: php regex url


【解决方案1】:

使用惰性匹配。

只需将?(?:[^\s()&lt;&gt;]+|\(([^\s()&lt;&gt;]+|(\([^\s()&lt;&gt;]+\)))*\))+? 相加即可节省大量计算资源。我还加了一个?在下一个非捕获组。这是一个更新的版本:

(?i)\b(?!.*?\<<)
(?!.*?\.onion)
((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|ftp:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)
 (?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+?
 (?:\(([^\s()<>]+|(\([^\s()<>]+\)))*?\)
 |
 [^\s`!()\[\]{};:\'".,<>?«»“”‘’])
)

demo

【讨论】:

  • 谢谢,这确实解决了灾难性回溯的问题。不幸的是,它还破坏了我的测试列表中的其他一些 URL:regex101.com/r/cI5eT2/4
【解决方案2】:

这应该可以正常工作: /(http[s]?://|www.)\w[^\s|

【讨论】:

    猜你喜欢
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-17
    • 2013-07-13
    • 2012-03-02
    • 1970-01-01
    相关资源
    最近更新 更多