代码之家  ›  专栏  ›  技术社区  ›  tsilb

这个正则表达式匹配但不应该匹配。为什么?

  •  5
  • tsilb  · 技术社区  · 15 年前

    这个正则表达式:

    ^((http)?| 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]+)(\)?)+?)(\.)([a-z]{2} [COM.O.G.N.G.V.I.I.I.BIZ.BiFiffiMabi,No.AyooWorksOffice(博物馆))([AZ-Z-Z-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.谷歌公司

    不应该是。这是我的“失败”测试用例之一。我已经声明在alpha而不是ip上进行匹配时,url的tld部分是必需的,并且“google”不适合“[a-z]{2}”子句。

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

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

    我的正则表达式怎么了?

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



    edit2:已修复-更正的regex(按要求)为:

    ^((http)?| 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,O.G.O.G.net,GoV.MiL.Biz,Fippi,Mabi,No.[A] [\/AZ-Z0-9\[*])*([/])?[\?][A-ZA-Z0-9\=\&\%\/]*)?$
    3 回复  |  直到 15 年前
        1
  •  12
  •   Amber    15 年前

    “谷歌”可能不适合 [a-z]{2} ,但它确实适合 [a-z]{2}([a-zA-Z0-9\?\=\&\%\/]*)? -你忘了要求 / 如果url超出域,则在tld之后。所以它用“www.go”作为域名,然后“ogle”跟着它,中间没有斜线。您可以通过添加 [?/] 到最后一个组的前面,要求tld和url的任何其他部分之间的这两个符号之一。

        2
  •  2
  •   Kaivosukeltaja    15 年前

    tld子句匹配go ogle中的“go”,querystring支持部分随后匹配“ogle”。尝试将querystring部分更改为:

    ([?/][a-zA-Z0-9\?\=\&\%\/]*)?
    
        3
  •  2
  •   AnthonyWJones    15 年前

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

    但是“去”会,然后“妖怪”会匹配“([a-za-z0-9\?\=\&\%/]*)?“