regex - 需要正则表达式来验证 URL 并支持 %20 和 ()

标签 regex validation url url-validation

我目前正在使用以下正则表达式来验证 URL:

^(?#Protocol)(?:(?:ht|f)tp(?:s?)\:\/\/|~\/|\/)?(?#Username:Password)(?:\w+:\w+@)?  (?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|edu|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:\/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|\/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=?(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$

我从网络上的某个地方借了这个(不记得在哪里)来改进这个:
^((https?|file|ftp|gopher|news|nntp):\/\/)([a-z]([a-z0-9\-]*\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)|(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-z][a-z0-9_]*)?$

但是,这些都不能验证这个 url(应该是有效的):
http://somedomain.com/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg

问题是 %20 和圆括号 ()。尽我所能,我无法让上面的任何一个正则表达式来正确验证上面的 url 而不会破坏其他东西。我没有编写花哨的正则表达式的经验,所以这也无济于事。我发现的所有其他网络结果在诸如此类的愚蠢事情上都失败了:
http://www.test..com

帮助将不胜感激。

最佳答案

您正在使用相同的正则表达式验证两件事:

  • 格式正确——语法正确吗?
  • 似是而非——协议(protocol)和顶级域是否似是而非?

  • 分离这些验证可能是富有成效的。您可以使用此正则表达式来检查 URI 的格式是否正确。来自 RFC 3986, Uniform Resource Identifiers (URI): Generic Syntax ,附录 B(第 50 页):
    ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
    

    如果 URI 与此正则表达式匹配,则它的格式正确。比赛组为您提供各种作品,它们是:
    scheme    = $2
    authority = $4
    path      = $5
    query     = $7
    fragment  = $9
    

    让我们看看您提供的示例 URI 的结果:
    2 (scheme)   : "http"
    4 (authority): "somedomain.com"
    5 (path)     : "/users/1234/images/Staff%20Photos%202008/FirstName%20LastName_1%20(Small).jpg"
    7 (query)    : nil
    9 (fragment) : nil
    

    现在您已经获得了各个部分,您可以检查每个部分的合理性。例如,要从权威机构获取 TLD,请将此正则表达式应用于权威机构:
    \.([^.])$
    

    第 1 组为您提供 TLD(com、org 等),然后您可以对照您的列表进行检查。

    关于regex - 需要正则表达式来验证 URL 并支持 %20 和 (),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2068405/

    相关文章:

    java - 如何根据正则表达式更改 XML 与文本(字符数据)的匹配

    java - 2 个不同字符串的正则表达式说明可选元素

    javascript - 使用正则表达式按空格和逗号分割字符串

    HTML 输入模式验证不起作用

    django - 如何在 Django 模板中将名称反转为绝对 URL?

    html - itemprop=图片元素上的 url 属性未验证

    java 正则表达式与电子邮件验证问题

    php - Laravel 验证 - 以逗号分隔的字符串输入为数组

    python - 如何在django View 中检查数据是否为 'null'?

    c# - 混合 ASP.NET 和 MVC 路由