需要正则表达式来验证网址并支持%20和()

时间:2010-01-14 23:49:36

标签: regex validation url url-validation

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

^(?#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

帮助将不胜感激。

1 个答案:

答案 0 :(得分:4)

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

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

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