【问题标题】:How to write a regular expression pattern that is capable of validating URIs?正则表达式来验证 URI
【发布时间】:2010-09-07 01:08:48
【问题描述】:

如何生成只匹配有效 URI 的正则表达式。可以在此处找到 URI 的描述:http://en.wikipedia.org/wiki/URI_scheme。它不需要提取任何部分,只需测试 URI 是否有效。

(首选格式是 .Net 正则表达式)(.Net 版本 1.1)

  • 无需检查已知协议,只需检查有效协议即可。

当前解决方案:

^([a-zA-Z0-9+.-]+):(//([a-zA-Z0-9-._~!$&'()*+,;=:]*)@)?([a-zA-Z0-9-._~!$&'()*+,;=]+)(:(\\d*))?(/?[a-zA-Z0-9-._~!$&'()*+,;=:/]+)?(\\?[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?(#[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?$(:(\\d*))?(/?[a-zA-Z0-9-._~!$&'()*+,;=:/]+)?(\?[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?(\#[a-zA-Z0-9-._~!$&'()*+,;=:/?@]+)?$

【问题讨论】:

    标签: .net regex


    【解决方案1】:

    Uri.IsWellFormedUriString 适合你吗?

    【讨论】:

    • +1 这是唯一正确的答案。正则表达式不是该工作的正确工具。我总是想知道使用正则表达式解析 Uri 的标准兼容和安全性如何。处理国际化(unicode)域?混淆真实路径的编码?容错?测试了吗?只需使用 .net 框架!
    【解决方案2】:

    URI specification says

    以下行是将格式良好的 URI 引用分解为其组件的正则表达式。

    ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?

    (我猜这与另一个答案中给出的 STD66 链接中的正则表达式相同。)

    但是故障不是验证。要正确验证 URI,必须将 BNF for URIs 转换为正则表达式。虽然有些 BNF不能 表示为正则表达式,但我认为用这个 可以 完成。但它不应该这样做——这将是一个巨大的混乱。最好使用库函数。

    【讨论】:

      【解决方案3】:

      这个网站看起来很有前途:http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/

      他们提出以下正则表达式:

      /^([a-z0-9+.-]+):(?://(?:((?:[a-z0-9-._~!$&'()*+,;=:]|%[0-9A-F]{2})*)@)?((?:[a-z0-9-._~!$&'()*+,;=]|%[0-9A-F]{2})*)(?::(\d*))?(/(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?|(/?(?:[a-z0-9-._~!$&'()*+,;=:@]|%[0-9A-F]{2})+(?:[a-z0-9-._~!$&'()*+,;=:@/]|%[0-9A-F]{2})*)?)(?:\?((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?(?:#((?:[a-z0-9-._~!$&'()*+,;=:/?@]|%[0-9A-F]{2})*))?$/i
      

      【讨论】:

      【解决方案4】:

      我找到的最好和最权威的指南在这里:http://jmrware.com/articles/2009/uri_regexp/URI_regex.html(回答您的问题,请参阅 URI 表条目)

      来自 RFC3986 的所有这些规则都在表 2 中重现,以及每个规则的正则表达式实现。

      这里有一个 javascript 实现:https://github.com/jhermsmeier/uri.regex

      作为参考,URI 正则表达式在下面重复:

      # RFC-3986 URI component:  URI
      [A-Za-z][A-Za-z0-9+\-.]* :                                      # scheme ":"
      (?: //                                                          # hier-part
        (?: (?:[A-Za-z0-9\-._~!$&'()*+,;=:]|%[0-9A-Fa-f]{2})* @)?
        (?:
          \[
          (?:
            (?:
              (?:                                                    (?:[0-9A-Fa-f]{1,4}:)    {6}
              |                                                   :: (?:[0-9A-Fa-f]{1,4}:)    {5}
              | (?:                            [0-9A-Fa-f]{1,4})? :: (?:[0-9A-Fa-f]{1,4}:)    {4}
              | (?: (?:[0-9A-Fa-f]{1,4}:){0,1} [0-9A-Fa-f]{1,4})? :: (?:[0-9A-Fa-f]{1,4}:)    {3}
              | (?: (?:[0-9A-Fa-f]{1,4}:){0,2} [0-9A-Fa-f]{1,4})? :: (?:[0-9A-Fa-f]{1,4}:)    {2}
              | (?: (?:[0-9A-Fa-f]{1,4}:){0,3} [0-9A-Fa-f]{1,4})? ::    [0-9A-Fa-f]{1,4}:
              | (?: (?:[0-9A-Fa-f]{1,4}:){0,4} [0-9A-Fa-f]{1,4})? ::
              ) (?:
                  [0-9A-Fa-f]{1,4} : [0-9A-Fa-f]{1,4}
                | (?: (?: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]?)
                )
            |   (?: (?:[0-9A-Fa-f]{1,4}:){0,5} [0-9A-Fa-f]{1,4})? ::    [0-9A-Fa-f]{1,4}
            |   (?: (?:[0-9A-Fa-f]{1,4}:){0,6} [0-9A-Fa-f]{1,4})? ::
            )
          | [Vv][0-9A-Fa-f]+\.[A-Za-z0-9\-._~!$&'()*+,;=:]+
          )
          \]
        | (?:(?: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\-._~!$&'()*+,;=]|%[0-9A-Fa-f]{2})*
        )
        (?: : [0-9]* )?
        (?:/ (?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})* )*
      | /
        (?:    (?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+
          (?:/ (?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})* )*
        )?
      |        (?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})+
          (?:/ (?:[A-Za-z0-9\-._~!$&'()*+,;=:@]|%[0-9A-Fa-f]{2})* )*
      |
      )
      (?:\? (?:[A-Za-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )?   # [ "?" query ]
      (?:\# (?:[A-Za-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})* )?   # [ "#" fragment ]
      

      【讨论】:

      • 所有正则表达式的好妈妈,我的同事认为我对使用和理解正则表达式很着迷......
      【解决方案5】:

      我根据 RFC 3986 (https://www.rfc-editor.org/rfc/rfc3986) 提出的最佳正则表达式如下:

      // named groups
      /^(?<scheme>[a-z][a-z0-9+.-]+):(?<authority>\/\/(?<user>[^@]+@)?(?<host>[a-z0-9.\-_~]+)(?<port>:\d+)?)?(?<path>(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])+(?:\/(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])*)*|(?:\/(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])+)*)?(?<query>\?(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@]|[/?])+)?(?<fragment>\#(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@]|[/?])+)?$/i
      
      // unnamed groups
      /^([a-z][a-z0-9+.-]+):(\/\/([^@]+@)?([a-z0-9.\-_~]+)(:\d+)?)?((?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])+(?:\/(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])*)*|(?:\/(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@])+)*)?(\?(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@]|[/?])+)?(\#(?:[a-z0-9-._~]|%[a-f0-9]|[!$&'()*+,;=:@]|[/?])+)?$/i
      

      捕获组

      1. 方案
      2. 权限
      3. 用户信息
      4. 主持人
      5. 端口
      6. 路径
      7. 查询
      8. 片段

      【讨论】:

      【解决方案6】:

      是否有一些您关心的特定 URI,或者您是否试图找到一个验证 STD66 的正则表达式?

      我打算将您指向 this regex 以解析 URI。然后,理论上,您可以检查您关心的所有元素是否都在那里。

      但我认为bdukes的答案更好。

      【讨论】:

        猜你喜欢
        • 2011-08-02
        • 1970-01-01
        • 1970-01-01
        • 2010-11-24
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多