【问题标题】:This regex matches and shouldn't. Why is it?这个正则表达式匹配并且不应该。为什么?
【发布时间】:2010-12-10 09:58:02
【问题描述】:

这个正则表达式:

^((https?|ftp)\:(\/\/)|(文件\:\/{2,3}))?(((25[0-5]|2[0-4][0- 9]|[01]?[0-9][0-9]?)\.){3} (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((([a-zA-Z0-9 ]+)(\.)?)+?)(\.)([az]{2} |com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum))([a-zA-Z0-9\?\=\&\%\/]*)?$

为便于阅读而格式化:

^( # Begin regex / begin address clause
  (https?|ftp)\:(\/\/)|(file\:\/{2,3}))? # protocol
  ( # container for two address formats, more to come later
   ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
   (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) # match IP addresses
  )|( # delimiter for address formats
   ((([a-zA-Z0-9]+)(\.)?)+?) # match domains and any number of subdomains
   (\.) #dot for .com
   ([a-z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum) #TLD clause
  ) # end address clause
([a-zA-Z0-9\?\=\&\%\/]*)? # querystring support, will pretty this up later
$

匹配:

www.google

而且不应该。这是我的“失败”测试用例之一。我已声明当在 alpha 而不是 IP 上匹配时,URL 的 TLD 部分是强制性的,并且“google”不适合“[a-z]{2}”子句。

请记住,我将分别解决以下问题 - 这个问题是关于为什么它与 www.google 匹配而不应该匹配。

  • 查询字符串只需要支持正确的格式,目前接受查询字符串字符的任意组合
  • 一些协议不受支持,但我的要求范围可能不包括它们
  • 不包括 3 个字符的不常见 TLD
  • 可能匹配 http://www.google..com - 将检查连续的点
  • 不支持十进制 IP 地址格式

我的正则表达式有什么问题?

编辑:另请参阅此正则表达式的早期版本在不同测试用例上的先前问题: How can I make this regex match correctly?



edit2:固定 - 更正的正则表达式(如要求)是:

^((https?|ftp)\:(\/\/)|(文件\:\/{2,3}))?(((25[0-5]|2[0-4][0- 9]|[01]?[0-9][0-9]?)\.){3} (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((([a-zA-Z0-9 ]+)(\.)?)+?)(\.)([az]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum))( [\/][\/a-zA-Z0-9\.]*)*?([\/]?[\?][a-zA-Z0-9\=\&\%\/]*) ?$

【问题讨论】:

  • 我不会说 question 是完全重复的,但肯定 answer 应该是。
  • 不,那个有不同的正则表达式,如果我编辑它,没有人会回到它。
  • ...而且,这场比赛与我问的那场比赛不同。
  • 好的,如果不是“完全重复”那么“高度相关”和对回答者有用的链接。以后,如果您指的是以前的问题,请说出来,以便回答者可以了解您以前学到的内容。

标签: regex


【解决方案1】:

google" 不适合 "[a-z]{2}" 子句。

但是“go”会匹配,然后“ogle”匹配“([a-zA-Z0-9\?\=\&\%/]*)?”

【讨论】:

    【解决方案2】:

    您的 TLD 子句在 google 中匹配“go”,之后查询字符串支持部分匹配“ogle”。尝试将查询字符串部分更改为:

    ([?/][a-zA-Z0-9\?\=\&\%\/]*)?
    

    【讨论】:

    • 呸,没错,当我删除了专门格式化的查询字符串的东西(失败,我想我会在其余部分工作后修复它),我忘记了它不再分隔问号!
    【解决方案3】:

    “google”可能不适合 [a-z]{2},但它确实适合 [a-z]{2}([a-zA-Z0-9\?\=\&\%\/]*)? - 如果 URL 超出域,您忘记在 TLD 之后要求 /。所以它将“www.go”解释为域,然后“ogle”跟随它,中间没有斜线。您可以通过在最后一组前面添加 [?/] 来修复它,以要求 TLD 和 URL 的任何其他部分之间的这两个符号之一。

    【讨论】:

    • 所以example.com?a=b&c=d 不是有效的网址,因为 ?? 之前没有 /
    • @tslib:它实际上不是一个有效的 url。
    • @Residuum:那为什么 C# 的 Request.Querystring[] 会选择它? :)
    • @tsilb:您的示例实际上是一个有效的 URL。几天前这里有一个关于这个确切案例的问题,但由于基本上不可能搜索“com?”恐怕我找不到它的链接。
    • tsilb:我建议添加 [?/] 而不仅仅是 / 是有原因的 - 因为任何一个都是有效的。
    猜你喜欢
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多