【问题标题】:Need a regex to validating a Url and support %20 and ()需要正则表达式来验证 URL 并支持 %20 和 ()
【发布时间】:2011-01-05 07:41:13
【问题描述】:

我目前正在使用以下正则表达式来验证 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

我们将不胜感激。

【问题讨论】:

  • 我不认为正则表达式是正确的工具。您是否有理由必须使用正则表达式?
  • 您使用什么语言?也许还有另一种方法来验证它。
  • 嗨,我实际上是在使用 C# 在 ASP.NET MVC 中编写一个 Web 应用程序。我的验证层使用正则表达式来确保输入的 URL 有效(很像电子邮件和电话验证)。 URL 指示文件在 Internet 和 Intranet 上的位置。在发布表单时,您是否发现了比正则表达式更好的验证方式?

标签: regex validation url url-validation


【解决方案1】:

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

  • 格式正确 -- 语法正确吗?
  • 合理 -- 协议和顶级域是否合理?

将这些验证分开可能会很有成效。您可以使用此正则表达式来检查 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 等),然后您可以对照您的列表进行检查。

【讨论】:

  • 我实际上从未听说过不使用单个正则表达式来测试形式和合理性。这个想法很好,但需要做更多的工作。你有推荐的(路径)正则表达式吗?
  • 我认为您不需要为路径添加额外的正则表达式。对于权限,请使用我在上面给出的正则表达式来提取它并根据您的列表(com、org 等)检查它。根据您的列表(http、ftp 等)检查方案。我不会检查太多——只要知道它的格式已经让你受益匪浅;更多的检查将产生越来越少的好处,代价是导致您现在或将来引入新的 TLD 和协议时拒绝好的 URI。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2021-02-24
相关资源
最近更新 更多