To clarify, I’m looking for a decent regular expression to validate URLs that were entered as user input with. I have no interest in parsing a list of URLs from a given string of text (even though some of the regexes on this page are capable of doing that). I also don’t want to allow every possible technically valid URL — quite the opposite. See the URL Standard if you’re looking to parse URLs in the same way that browsers do.

Assume that this regex will be used for a public URL shortener written in PHP, so URLs like http://localhost///foo.bar/://foo.bar/data:text/plain;charset=utf-8,OHAI and tel:+1234567890 shouldn’t pass (even though they’re technically valid). Also, in this case I only want to allow the HTTP, HTTPS and FTP protocols.

Also, single weird leading and/or trailing characters aren’t tested for. Just imagine you’re doing this before testing $url with the regex:

$url = trim($url, '!"#$%&\'()*+,-./@:;<=>[\\]^_`{|}~');

Note that I’ve added the S modifier to all the regexes to speed up the tests. In real-world usage, this modifier can be omitted.

Here’s a plain text list of all the URLs used in the test.

Diego Perini posted his version as a gist.

URL Spoon Library @krijnhoetmer @gruber @gruber v2 @cowboy Jeffrey Friedl @mattfarina @stephenhay @scottgonzales @rodneyrehm @imme_emosol @diegoperini Using filter_var()
These URLs should match (1 → correct)
http://foo.com/blah_blah 1 1 1 1 1 1 1 1 1 1 1 1 1
http://foo.com/blah_blah/ 1 1 1 1 1 1 1 1 1 1 1 1 1
http://foo.com/blah_blah_(wikipedia) 1 1 1 1 1 1 1 1 1 0 1 1 1
http://foo.com/blah_blah_(wikipedia)_(again) 1 1 1 1 1 1 1 1 1 0 1 1 1
http://www.example.com/wpstyle/?p=364 1 1 1 1 1 1 1 1 1 1 1 1 1
https://www.example.com/foo/?bar=baz&inga=42&quux 1 1 1 1 1 1 1 1 1 1 1 1 1
http://✪df.ws/123 0 0 1 1 1 1 0 1 1 1 1 1 0
http://userid:password@example.com:8080 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid:password@example.com:8080/ 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid@example.com 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid@example.com/ 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid@example.com:8080 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid@example.com:8080/ 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid:password@example.com 0 1 1 1 1 0 1 1 1 1 1 1 1
http://userid:password@example.com/ 0 1 1 1 1 0 1 1 1 1 1 1 1
http://142.42.1.1/ 0 1 1 1 1 1 1 1 1 1 1 1 1
http://142.42.1.1:8080/ 0 1 1 1 1 1 1 1 1 1 1 1 1
http://➡.ws/䨹 0 0 1 1 1 0 0 1 1 0 1 1 0
http://⌘.ws 0 0 1 1 1 0 0 1 1 1 1 1 0
http://⌘.ws/ 0 0 1 1 1 0 0 1 1 1 1 1 0
http://foo.com/blah_(wikipedia)#cite-1 1 1 1 1 1 1 1 1 1 1 1 1 1
http://foo.com/blah_(wikipedia)_blah#cite-1 1 1 1 1 1 1 1 1 1 1 1 1 1
http://foo.com/unicode_(✪)_in_parens 1 1 1 1 1 1 0 1 1 1 1 1 0
http://foo.com/(something)?after=parens 1 1 1 1 1 1 1 1 1 1 1 1 1
http://☺.damowmow.com/ 0 1 1 1 1 0 0 1 1 1 1 1 0
http://code.google.com/events/#&product=browser 1 1 1 1 1 1 1 1 1 1 1 1 1
http://j.mp 1 1 1 1 1 1 1 1 1 1 1 1 1
ftp://foo.bar/baz 0 0 1 1 1 1 1 1 1 1 1 1 1
http://foo.bar/?q=Test%20URL-encoded%20stuff 0 1 1 1 1 1 1 1 1 1 1 1 1
http://مثال.إختبار 0 0 1 1 1 0 0 1 1 0 1 1 0
http://例子.测试 0 0 1 1 1 0 0 1 1 0 1 1 0
http://उदाहरण.परीक्षा 0 0 1 1 1 0 0 1 1 0 1 1 0
http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com 0 1 0 1 1 0 0 1 1 1 1 1 1
http://1337.net 1 1 1 1 1 1 1 1 1 1 1 1 1
http://a.b-c.de 1 1 1 1 1 1 1 1 1 1 0 1 1
http://223.255.255.254 0 1 1 1 1 1 1 1 1 1 1 1 1
These URLs should fail (0 → correct)
http:// 0 0 0 0 0 0 0 0 1 0 0 0 0
http://. 0 0 0 0 1 0 1 0 1 0 0 0 0
http://.. 0 0 0 0 1 0 1 0 1 0 0 0 0
http://../ 0 1 1 1 1 0 1 0 1 1 0 0 0
http://? 0 0 0 0 1 0 0 0 1 0 0 0 0
http://?? 0 0 0 0 1 0 0 0 1 0 0 0 0
http://??/ 0 1 1 1 1 0 0 0 1 1 0 0 0
http://# 0 0 0 1 1 0 0 0 1 1 0 0 0
http://## 0 1 0 1 1 0 0 0 1 1 0 0 0
http://##/ 0 1 1 1 1 0 0 0 1 1 0 0 0
http://foo.bar?q=Spaces should be encoded 0 1 1 1 1 1 0 0 1 1 0 0 0
// 0 0 0 0 0 0 0 0 0 0 0 0 0
//a 0 0 0 0 0 0 0 0 0 0 0 0 0
///a 0 0 0 0 0 0 0 0 0 0 0 0 0
/// 0 0 0 0 0 0 0 0 0 0 0 0 0
http:///a 0 1 1 1 1 0 0 0 1 1 0 0 0
foo.com 0 0 0 0 1 0 0 0 0 0 0 0 0
rdar://1234 0 0 1 1 1 0 1 0 1 0 0 0 1
h://test 0 0 1 0 1 0 1 0 1 0 0 0 1
http:// shouldfail.com 0 0 0 0 1 0 0 0 1 1 0 0 0
:// should fail 0 0 0 0 0 0 0 0 0 0 0 0 0
http://foo.bar/foo(bar)baz quux 0 1 1 1 1 1 0 0 1 1 0 0 0
ftps://foo.bar/ 0 0 1 1 1 0 1 0 1 0 0 0 1
http://-error-.invalid/ 0 1 1 1 1 1 1 1 1 1 0 0 0
http://a.b--c.de/ 1 1 1 1 1 1 1 1 1 1 0 0 1
http://-a.b.co 1 1 1 1 1 1 1 1 1 1 0 0 0
http://a.b-.co 1 1 1 1 1 1 1 1 1 1 0 0 1
http://0.0.0.0 0 1 1 1 1 1 1 1 1 1 1 0 1
http://10.1.1.0 0 1 1 1 1 1 1 1 1 1 1 0 1
http://10.1.1.255 0 1 1 1 1 1 1 1 1 1 1 0 1
http://224.1.1.1 0 1 1 1 1 1 1 1 1 1 1 0 1
http://1.1.1.1.1 0 1 1 1 1 1 1 1 1 1 1 0 1
http://123.123.123 0 1 1 1 1 1 1 1 1 1 1 0 1
http://3628126748 0 1 1 1 1 0 1 1 1 1 1 0 1
http://.www.foo.bar/ 0 1 1 1 1 0 1 0 1 1 0 0 0
http://www.foo.bar./ 0 1 1 1 1 1 1 1 1 1 1 0 0
http://.www.foo.bar./ 0 1 1 1 1 0 1 0 1 1 0 0 0
http://10.1.1.1 0 1 1 1 1 1 1 1 1 1 1 0 1
http://10.1.1.254 0 1 1 1 1 1 1 1 1 1 1 0 1

Spoon Library (979 chars)

/(((http|ftp|https):\/{2})+(([0-9a-z_-]+\.)+(aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mn|mo|mp|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|nom|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ra|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw|arpa)(:[0-9]+)?((\/([~0-9a-zA-Z\#\+\%@\.\/_-]+))?(\?[0-9a-zA-Z\+\%@\/&\[\];=_-]+)?)?))\b/imuS

@krijnhoetmer (115 chars)

_(^|[\s.:;?\-\]<\(])(https?://[-\w;/?:@&=+$\|\_.!~*\|'()\[\]%#,☺]+[\w/#](\(\))?)(?=$|[\s',\|\(\).:;?\-\[\]>\)])_i

@gruber (71 chars)

#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#iS

@gruber v2 (218 chars)

#(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))#iS

@cowboy (1241 chars)

~(?:\b[a-z\d.-]+://[^<>\s]+|\b(?:(?:(?:[^\s!@#$%^&*()_=+[\]{}\|;:'",.<>/?]+)\.)+(?:ac|ad|aero|ae|af|ag|ai|al|am|an|ao|aq|arpa|ar|asia|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|biz|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|cat|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|coop|com|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|info|int|in|io|iq|ir|is|it|je|jm|jobs|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mobi|mo|mp|mq|mr|ms|mt|museum|mu|mv|mw|mx|my|mz|name|na|nc|net|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pro|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|travel|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)|(?:(?:[0-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[0-9]|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))(?:[;/][^#?<>\s]*)?(?:\?[^#<>\s]*)?(?:#[^<>\s]*)?(?!\w))~iS

Jeffrey Friedl (241 chars)

@\b((ftp|https?)://[-\w]+(\.\w[-\w]*)+|(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\.)+(?: com\b|edu\b|biz\b|gov\b|in(?:t|fo)\b|mil\b|net\b|org\b|[a-z][a-z]\b))(\:\d+)?(/[^.!,?;"'<>()\[\]{}\s\x7F-\xFF]*(?:[.!,?]+[^.!,?;"'<>()\[\]{}\s\x7F-\xFF]+)*)?@iS

@mattfarina (287 chars)

/^([a-z][a-z0-9\*\-\.]*):\/\/(?:(?:(?:[\w\.\-\+!$&'\(\)*\+,;=]|%[0-9a-f]{2})+:)*(?:[\w\.\-\+%!$&'\(\)*\+,;=]|%[0-9a-f]{2})+@)?(?:(?:[a-z0-9\-\.]|%[0-9a-f]{2})+|(?:\[(?:[0-9a-f]{0,4}:)*(?:[0-9a-f]{0,4})\]))(?::[0-9]+)?(?:[\/|\?](?:[\w#!:\.\?\+=&@!$'~*,;\/\(\)\[\]\-]|%[0-9a-f]{2})*)?$/xiS

@stephenhay (38 chars)

@^(https?|ftp)://[^\s/$.?#].[^\s]*$@iS

@scottgonzales (1347 chars)

#([a-z]([a-z]|\d|\+|-|\.)*):(\/\/(((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?((\[(|(v[\da-f]{1,}\.(([a-z]|\d|-|\.|_|~)|[!\$&'\(\)\*\+,;=]|:)+))\])|((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=])*)(:\d*)?)(\/(([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*|(\/((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)|((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)|((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)){0})(\?((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\xE000-\xF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\x00A0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?#iS

@rodneyrehm (109 chars)

#((https?://|ftp://|www\.|[^\s:=]+@www\.).*?[a-z_\/0-9\-\#=&])(?=(\.|,|;|\?|\!)?("|'|«|»|\[|\s|\r|\n|$))#iS

@imme_emosol (54 chars)

@(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?$@iS

@diegoperini (502 chars)

_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:/[^\s]*)?$_iuS

— Mathias

In search of the perfect URL validation regex的更多相关文章

  1. URL validation failed. The error could have been caused through the use of the browser&#39;s navigation

    URL validation failed. The error could have been caused through the use of the browser's navigation ...

  2. java中url正则regex匹配

    String regex = "^(?:https?://)?[\\w]{1,}(?:\\.?[\\w]{1,})+[\\w-_/?&=#%:]*$"; 解释说明: ^ : ...

  3. R12.2 URL Validation failed. The error could have been caused through the use of the browser's navigation buttons

    EBS升级到R12.2.4后,进入系统操作老是报以下错误: 通过谷歌发现有人遇到相同的问题,并提供了解决方案. 原文地址:http://onlineappsdbaoracle.blogspot.com ...

  4. [PHP]正则表达式判断网址

    来源:https://segmentfault.com/q/1010000000584340/a-1020000000584362 Markdown 的作者之一写的正则表达式(原文在这) (?i)\b ...

  5. 使用jquery.validation+jquery.poshytip做表单验证--未完待续

    jqueryValidate的具体使用方法很多,这里就不在赘述,这一次只谈一下怎样简单的实现表单验证. 整片文章目的,通过JQvalidation按表单属性配置规则验证,并将验证结果通过poshyti ...

  6. [转]nginx下的url rewrite

    转:http://zhengdl126.iteye.com/blog/698206 if (!-e $request_filename){rewrite "^/index\.html&quo ...

  7. AngularJS通过$location获取及改变当前页面的URL

    本文中获取与修改的URL以 ‘http://172.16.0.88:8100/#/homePage?id=10&a=100' 这个路径为例: 一. 获取url的相关方法(不修改URL): 1. ...

  8. Angular 通过注入 $location 获取与修改当前页面URL

    //1.获取当前完整的url路径 var absurl = $location.absUrl(); //http://172.16.0.88:8100/#/homePage?id=10&a=1 ...

  9. AngularJS如何修改URL中的参数

    一. 获取url的相关方法(不修改URL): 1.获取当前完整的url路径 var absurl = $location.absUrl(); //http://172.16.0.88:8100/#/h ...

随机推荐

  1. java面试第十四天

    包名.类名和属性可以被序列化,方法和构造器不会被序列化的. 静态属性不会被序列化的. 属性会被递归序列化的,也就是一个类中有引用类型的属性,如果这个属性对应的类实现了Serializable接口,在对 ...

  2. 〖Linux〗Ubuntu13.10,声音图标调节音量失效的解决办法

    升级Ubuntu13.10,发现声音图标不能调节音量[XUbuntu13.10发行日志]: 临时解决办法: gvim /usr/share/dbus-1/services/indicator-soun ...

  3. 【Linux】shell数学运算

    在Bash shell环境中,可以利用let.(())和[]执行基本的算术操作.而在进行高级操作时,expr和bc这两个工具就特别有用 let的使用 Script01.sh #!/bin/bash # ...

  4. 按部就班——图解配置IIS5的SSL安全访问(转)

    作者:mikespook 版本:1.0 最后更新:2004-12-22 16:04 按部就班——图解配置IIS5的SSL安全访问... 1 写在前面的... 1 第一步:       准备工作... ...

  5. JSP,servlet和数据库之间传值出现乱码的问题

     近期困扰我非常久的一个问题最终攻克了,为他我头疼了好几天,问题是JSP通过servlet向数据库传值,查询显示在页面的时候出现了乱码,原先我数据库中有两行带有中文的数据,查询的时候倒是没有出现乱 ...

  6. Mysql 5.7 从节点配置多线程主从复制

    Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有一个线 ...

  7. LeetCode-342:Power of Four

    This  is another  "Pick One" Problem :[Problem:342-Power of Four] Given an integer (signed ...

  8. 阿里云ECS服务器Linux环境下配置php服务器(一)--基础配置篇

    开始安装软件了,我们需要安装的软件有apache,php和MySQL. ps:如果你购买的是北京的服务器,有个安全组需要设置,我全部用的默认设置,暂时还没发现会有什么影响. 首先关闭SELINUX(S ...

  9. 【jQuery】网上看到一个不错的登陆界面

    预览截图如下: Html部分代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  10. C语言笔记本

    在此记录一些常见的C语言错误,可以当作学习C语言的笔记,需要的时候可以回过头看看. 1.关于“++” #include int main() { int a,b,cd; a=10; b=a++; c= ...