检查字符串是不是为有效 URL 的最佳正则表达式是啥?
Posted
技术标签:
【中文标题】检查字符串是不是为有效 URL 的最佳正则表达式是啥?【英文标题】:What is the best regular expression to check if a string is a valid URL?检查字符串是否为有效 URL 的最佳正则表达式是什么? 【发布时间】:2010-10-24 10:11:40 【问题描述】:如何检查给定的字符串是否是有效的 URL 地址?
我对正则表达式的了解很基础,无法从我已经在网上看到的数百个正则表达式中进行选择。
【问题讨论】:
任何 URL 或只是 HTTP?例如。 mailto:me@example.com 是否算作 URL? AIM 聊天链接? 如果一个 URL 没有前导“http(etc)”,你如何能够将它与任何其他恰好有点的任意字符串区分开来?说“MyClass.MyProperty.MyMethod”之类的话?或者“我有时会错过空格键。这是个问题吗?” 我已经添加了前缀'http://www.'在文本框之前。所以用户不需要输入'http://www.'并且应该只关心输入所需的 uri 名称。 您使用什么编程语言?您可能不想重新发明***。 Microsoft 有一个包含 URL 表达式的正则表达式页面。当然是一个好的开始:msdn.microsoft.com/en-us/library/ff650303.aspx NB。以上页面已停用,但表中的表达式基本上仍然有效,可供参考。推荐的 URL 表达式(对我来说很好用)是:"^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[ 0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+ &%\$#_]*)?$" 【参考方案1】:javascript 现在有一个名为 new URL()
的 URL 构造函数。它允许您完全跳过 REGEX。
/**
*
* The URL() constructor returns a newly created URL object representing
* the URL defined by the parameters.
*
* https://developer.mozilla.org/en-US/docs/Web/API/URL/URL
*
*/
let requestUrl = new URL('https://username:password@developer.mozilla.org:8080/en-US/docs/search.html?par1=abc&par2=123&par3=true#Recent');
let urlParts =
origin: requestUrl.origin,
href: requestUrl.href,
protocol: requestUrl.protocol,
username: requestUrl.username,
password: requestUrl.password,
host: requestUrl.host,
hostname: requestUrl.hostname,
port: requestUrl.port,
pathname: requestUrl.pathname,
search: requestUrl.search,
searchParams:
par1: String(requestUrl.searchParams.get('par1')),
par2: Number(requestUrl.searchParams.get('par2')),
par3: Boolean(requestUrl.searchParams.get('par3')),
,
hash: requestUrl.hash
;
console.log(urlParts);
【讨论】:
【参考方案2】:最好的正则表达式是这里最好的答案的组合!哈哈哈!我刚刚测试了所有这些,并将最好的放在一起!我稍微改变了一下,只有一个捕获组!我能在这个页面的源代码中找到 637 个 URL!只有少数误报!
((?:(?:https?|ftp)://)(?:\S+(?::\S*)?@|\d1,3(?:\.\d1,3)3|(?:(?:[a-z\d\x00a1-\xffff]+-?)*[a-z\d\x00a1-\xffff]+)(?:\.(?:[a-z\d\x00a1-\xffff]+-?)*[a-z\d\x00a1-\xffff]+)*(?:\.[a-z\x00a1-\xffff]2,6))(?::\d+)?(?:[^\s]*)|(?:(?:(?:[A-Za-z]3,9:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)(?:(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)|(?:(?:(?:(?:[A-Za-z]3,9:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)(?:(?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?))|(?:(?:(?:[\\w]+:)?//)?(?:(?:[\\d\\w]|%[a-fA-f\\d]2,2)+(?::(?:[\\d\\w]|%[a-fA-f\\d]2,2)+)?@)?(?:[\\d\\w][-\\d\\w]0,253[\\d\\w]\\.)+[\\w]2,4(?::[\\d]+)?(?:/(?:[-+_~.\\d\\w]|%[a-fA-f\\d]2,2)*)*(?:\\?(?:&?(?:[-+_~.\\d\\w]|%[a-fA-f\\d]2,2)=?)*)?(?:#(?:[-+_~.\\d\\w]|%[a-fA-f\\d]2,2)*)?)|(?:https?:\/\/(?:[a-z0-9](?:[a-z0-9-]0,61[a-z0-9])?\.)+[a-z0-9][a-z0-9-]0,61[a-z0-9])(?::?\d*)\/?(?:[a-z_\/0-9\-#.]*)\??(?:[a-z_\/0-9\-#=&]*)|(?:(?:(?:https?:)?(?:\/?\/))(?:(?:[\d\w]|%[a-fA-f\d]2,2)+(?::(?:[\d\w]|%[a-fA-f\d]2,2)+)?@)?(?:[\d\w][-\d\w]0,253[\d\w]\.)+[\w]2,63(?::[\d]+)?(?:/(?:[-+_~.\d\w]|%[a-fA-f\d]2,2)*)*(?:\?(?:&?(?:[-+_~.\d\w]|%[a-fA-f\d]2,2)=?)*)?(?:#(?:[-+_~.\d\w]|%[a-fA-f\d]2,2)*)?)|(?:(?:https?|ftp)://(?:www\d?|[a-zA-Z0-9]+)?\.[a-zA-Z0-9-]+(?:\:|\.)(?:[a-zA-Z0-9.]+|(?:\d+)?)(?:[/?:].*)?)|(?:\b(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d1,3)3)(?!127(?:\.\d1,3)3)(?!169\.254(?:\.\d1,3)2)(?!192\.168(?:\.\d1,3)2)(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d1,3)2)(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d1,2|2[0-4]\d|25[0-5]))2(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x00a1-\xffff0-9]+-?)*[a-z\x00a1-\xffff0-9]+)(?:\.(?:[a-z\x00a1-\xffff0-9]+-?)*[a-z\x00a1-\xffff0-9]+)*(?:\.(?:[a-z\x00a1-\xffff]2,)))(?::\d2,5)?(?:\/[^\s]*)?\b))
【讨论】:
【参考方案3】:以下正则表达式适用于我:
(http(s)?:\/\/.)?(ftp(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]0,256\.[a-z]
2,6\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)
匹配:
https://google.com t.me https://t.me ftp://google.com http://sm.tj http://bro.tj t.me/rshss https:google.com www.cool.com.au http://www.cool.com.au http://www.cool.com.au/ersdfs http://www.cool.com.au/ersdfs?dfd=dfgd@s=1 http://www.cool.com:81/index.html
【讨论】:
【参考方案4】:我写了一个你可以运行的小版本
它匹配以下网址(这对我来说已经足够了)
public static void main(args)
String url = "go to http://www.m.abut.ly/abc its awesome"
url = url.replaceAll(/https?:\/\/w0,3\w*?\.(\w*?\.)?\w2,3\S*|www\.(\w*?\.)?\w*?\.\w2,3\S*|(\w*?\.)?\w*?\.\w2,3[\/\?]\S*/ , it ->
"woof$itwoof"
)
println url
http://google.com
http://google.com/help.php
http://google.com/help.php?a=5
http://www.google.com
http://www.google.com/help.php
http://www.google.com?a=5
google.com?a=5
google.com/help.php
google.com/help.php?a=5
http://www.m.google.com/help.php?a=5 (and all its permutations)
www.m.google.com/help.php?a=5 (and all its permutations)
m.google.com/help.php?a=5 (and all its permutations)
对于不以 http
或 www
开头的任何 URL,重要的是它们必须包含 /
或 ?
我敢打赌,这可以稍微调整一下,但它的工作非常好,因为它如此短而紧凑......因为你几乎可以将它分成 3 部分:
查找以http
开头的任何内容:
https?:\/\/w0,3\w*?\.\w2,3\S*
查找以www
开头的任何内容:
www\.\w*?\.\w2,3\S*
或查找任何必须包含文本、点、至少 2 个字母和 ?
或 /
的内容:
\w*?\.\w2,3[\/\?]\S*
【讨论】:
这不支持 URL 中的-
。【参考方案5】:
对 URL 的简单检查是
^(ftp|http|https):\/\/[^ "]+$
【讨论】:
【参考方案6】:/^(http|HTTP)+(s|S)?:\/\/[\w.-]+(?:\.[\w\.-]+)+[\w\-\._\$\(\)/]+$/g
通过测试检查演示:
https://regexr.com/5cedu
【讨论】:
【参考方案7】:不管问的问题很广泛,我都会为将来寻找简单事物的任何人发布此内容...因为我认为验证 URL 没有适合所有需求的完美正则表达式,这取决于您的要求,即:就我而言,我只需要验证 URL 是否采用 domain.extension
的形式,并且我想允许 www
或任何其他子域,如 blog.domain.extension
我不关心 http(s),就像我的应用程序我有一个字段,上面写着“输入 URL”,所以很明显输入的字符串是什么。
所以这里是正则表达式:
/^(www\.|[a-zA-Z0-9](.*[a-zA-Z0-9])?\.)?((?!www)[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9])\.[a-z]2,5(:[0-9]1,5)?$/i
这个正则表达式的第一个块是:
(www\.|[a-zA-Z0-9](.*[a-zA-Z0-9])?\.)?
---> 我们开始检查 URL 是否以 www.
或 [a-zA-Z0-9](.*[a-zA-Z0-9])?
开头,这意味着一个字母或数字 + (anyCharacter(0 或多次) + 另一个字母或数字) 后跟一个点
注意(.*[a-zA-Z0-9])?\.)?
我们翻译成(anyCharacter(0 or multiple times) + another letterOrNumber)
是可选的(可以是或不是)这就是为什么我们将它放在括号之间并在后面加上问号?
到目前为止我们讨论的整个块也放在括号之间,然后是?这意味着 www 或任何其他词(代表子域)都是可选的。
第二部分是:((?!www)[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9])\.
---> 代表“域”部分,可以是任何以字母或数字开头的单词(www除外)+任何其他字母(包括破折号“-”)重复一次或多次,并以任何字母或数字结尾,后跟一个点。
最后一部分是[a-z]2,
---> 代表“扩展名”,可以是任何字母重复2次或多次,所以它可以是com、net、org、art基本上任何扩展名
【讨论】:
不适用于仅包含 2 个字符的域。【参考方案8】:以下表达式适用于所有热门域。它将接受以下网址:
www.yourwebsite.com http://www.yourwebsite.com www.yourwebsite.com yourwebsite.com yourwebsite.co.in此外,它还会以 url 作为链接发送消息
例如please visit yourwebsite.com
在上面的例子中,它会将yourwebsite.com
设为超链接
if (new RegExp("([-a-z0-9]1,63\\.)*?[a-z0-9][-a-z0-9]0,61[a-z0-9]\\.(com|com/|org|gov|cm|net|online|live|biz|us|uk|co.us|co.uk|in|co.in|int|info|edu|mil|ca|co|co.au|org/|gov/|cm/|net/|online/|live/|biz/|us/|uk/|co.us/|co.uk/|in/|co.in/|int/|info/|edu/|mil/|ca/|co/|co.au/)(/[-\\w@\\+\\.~#\\?*&/=% ]*)?$").test(strMessage) || (new RegExp("^[a-z ]+[\.]?[a-z ]+?[\.]+[a-z ]+?[\.]+[a-z ]+?[-\\w@\\+\\.~#\\?*&/=% ]*").test(strMessage) && new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]2,4)(:[0-9]+)?(/.*)?").test(strMessage)) || (new RegExp("^[a-z ]+[\.]?[a-z ]+?[-\\w@\\+\\.~#\\?*&/=% ]*").test(strMessage) && new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]2,4)(:[0-9]+)?(/.*)?").test(strMessage)))
if (new RegExp("^[a-z ]+[\.]?[a-z ]+?[\.]+[a-z ]+?[\.]+[a-z ]+?$").test(strMessage) && new RegExp("([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]2,4)(:[0-9]+)?(/.*)?").test(strMessage))
var url1 = /(^|<|\s)([\w\.]+\.(?:com|org|gov|cm|net|online|live|biz|us|uk|co.us|co.uk|in|co.in|int|info|edu|mil|ca|co|co.au))(\s|>|$)/g;
var html = $.trim(strMessage);
if (html)
html = html.replace(url1, '$1<a style="color:blue; text-decoration:underline;" target="_blank" href="http://$2">$2</a>$3');
returnString = html;
return returnString;
else
var url1 = /(^|<|\s)(www\..+?\.(?:com|org|gov|cm|net|online|live|biz|us|uk|co.us|co.uk|in|co.in|int|info|edu|mil|ca|co|co.au)[^,\s]*)(\s|>|$)/g,
url2 = /(^|<|\s)(((https?|ftp):\/\/|mailto:).+?\.(?:com|org|gov|cm|net|online|live|biz|us|uk|co.us|co.uk|in|co.in|int|info|edu|mil|ca|co|co.au)[^,\s]*)(\s|>|$)/g,
url3 = /(^|<|\s)([\w\.]+\.(?:com|org|gov|cm|net|online|live|biz|us|uk|co.us|co.uk|in|co.in|int|info|edu|mil|ca|co|co.au)[^,\s]*)(\s|>|$)/g;
var html = $.trim(strMessage);
if (html)
html = html.replace(url1, '$1<a style="color:blue; text-decoration:underline;" target="_blank" href="http://$2">$2</a>$3').replace(url2, '$1<a style="color:blue; text-decoration:underline;" target="_blank" href="$2">$2</a>$5').replace(url3, '$1<a style="color:blue; text-decoration:underline;" target="_blank" href="http://$2">$2</a>$3');
returnString = html;
return returnString;
【讨论】:
【参考方案9】:如果您想应用更严格的规则,这是我开发的:
isValidUrl(input)
var regex = /^(((H|h)(T|t)(T|t)(P|p)(S|s)?):\/\/)?[-a-zA-Z0-9@:%._\+~#=]2,100\.[a-zA-Z]2,10(\/([-a-zA-Z0-9@:%_\+.~#?&//=]*))?/
return regex.test(input)
【讨论】:
【参考方案10】:改进
检测如下 URL:
https://www.example.pl http://www.example.com www.example.pl example.com http://blog.example.com http://www.example.com/product http://www.example.com/products?id=1&page=2 http://www.example.com#up http://255.255.255.255 255.255.255.255 http://www.site.com:8008正则表达式:
/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/gm
【讨论】:
【参考方案11】:这是一个涵盖所有可能情况的好规则:端口、参数等
/(https?:\/\/(?:[a-z0-9](?:[a-z0-9-]0,61[a-z0-9])?\.)+[a-z0-9][a-z0-9-]0,61[a-z0-9])(:?\d*)\/?([a-z_\/0-9\-#.]*)\??([a-z_\/0-9\-#=&]*)/g
【讨论】:
这正是我想要的。【参考方案12】:我认为这是一个非常简单的方法。而且效果很好。
var hasURL = (str) =>
var url_pattern = new RegExp("(www.|http://|https://|ftp://)\w*");
if(!url_pattern.test(str))
document.getElementById("demo").innerHTML = 'No URL';
else
document.getElementById("demo").innerHTML = 'String has a URL';
;
<p>Please enter a string and test it has any url or not</p>
<input type="text" id="url" placeholder="url" onkeyup="hasURL(document.getElementById('url').value)">
<p id="demo"></p>
【讨论】:
你的正则表达式根本不起作用兄弟。它验证的只是您的字符串包含www
后跟one 字符(任何字符,因为您没有转义.
)或http://
或https://
或ftp://
并且任何这些可以后跟任何字母数字字符。因此,换句话说,以下所有字符串都将是有效的,但它们显然不是有效的 url:www.
、www▓
、£¢¤£¢¤www¢
(参见 regex101)。您可以使用更短的正则表达式:(www.|(https?|ftp)://)\w*
。 (顺便说一句,这仍然不是一个好的正则表达式)
显然是 www。 , www▓, £¢¤£¢¤www¢ 这些不是有效的网址。但我认为,那些也不是有意义的字符串。我只是尝试简化 url 模式。 @DrunkenPoney
我的目标不是编写 有意义的 字符串,而是表明奇怪的字符串会被接受,无论如何,因为你的正则表达式 validate for www
我想您不一定需要指定协议,但您的正则表达式不允许像google.com
这样的网址。此外,我试图向您展示的问题之一是,您的正则表达式匹配字符串中的任何验证部分(www
,http
,...)。您至少可以指定您的字符串需要以它开头。
如果你想要一个快速的正则表达式来验证 url 但不是 100% 安全 here 是我用来从 url 中提取不同部分但可以用来验证一个string 包含 url 的基本部分。【参考方案13】:
我编写了我的 URL(实际上是 IRI,国际化)模式以符合 RFC 3987 (http://www.faqs.org/rfcs/rfc3987.html)。这些都是 PCRE 语法。
对于绝对 IRI(国际化):
/^[a-z](?:[-a-z0-9\+\.])*:(?:\/\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:])*@)?(?:\[(?:(?:(?:[0-9a-f]1,4:)6(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|::(?:[0-9a-f]1,4:)5(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)4(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,1[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)3(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,2[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)2(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,3[0-9a-f]1,4)?::[0-9a-f]1,4:(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,4[0-9a-f]1,4)?::(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,5[0-9a-f]1,4)?::[0-9a-f]1,4|(?:(?:[0-9a-f]1,4:)0,6[0-9a-f]1,4)?::)|v[0-9a-f]+\.[-a-z0-9\._~!\$&'\(\)\*\+,;=:]+)\]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3|(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=])*)(?::[0-9]*)?(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|\/(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])))(?:\?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\xE000-\xF8FF\xF0000-\xFFFFD\x100000-\x10FFFD\/\?])*)?(?:\#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\/\?])*)?$/i
也允许相对 IRI:
/^(?:[a-z](?:[-a-z0-9\+\.])*:(?:\/\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:])*@)?(?:\[(?:(?:(?:[0-9a-f]1,4:)6(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|::(?:[0-9a-f]1,4:)5(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)4(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,1[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)3(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,2[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)2(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,3[0-9a-f]1,4)?::[0-9a-f]1,4:(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,4[0-9a-f]1,4)?::(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,5[0-9a-f]1,4)?::[0-9a-f]1,4|(?:(?:[0-9a-f]1,4:)0,6[0-9a-f]1,4)?::)|v[0-9a-f]+\.[-a-z0-9\._~!\$&'\(\)\*\+,;=:]+)\]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3|(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=])*)(?::[0-9]*)?(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|\/(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])))(?:\?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\xE000-\xF8FF\xF0000-\xFFFFD\x100000-\x10FFFD\/\?])*)?(?:\#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\/\?])*)?|(?:\/\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:])*@)?(?:\[(?:(?:(?:[0-9a-f]1,4:)6(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|::(?:[0-9a-f]1,4:)5(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)4(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,1[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)3(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,2[0-9a-f]1,4)?::(?:[0-9a-f]1,4:)2(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,3[0-9a-f]1,4)?::[0-9a-f]1,4:(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,4[0-9a-f]1,4)?::(?:[0-9a-f]1,4:[0-9a-f]1,4|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3)|(?:(?:[0-9a-f]1,4:)0,5[0-9a-f]1,4)?::[0-9a-f]1,4|(?:(?:[0-9a-f]1,4:)0,6[0-9a-f]1,4)?::)|v[0-9a-f]+\.[-a-z0-9\._~!\$&'\(\)\*\+,;=:]+)\]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))3|(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=])*)(?::[0-9]*)?(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|\/(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*)?|(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=@])+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])))(?:\?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\xE000-\xF8FF\xF0000-\xFFFFD\x100000-\x10FFFD\/\?])*)?(?:\#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD\xD0000-\xDFFFD\xE1000-\xEFFFD!\$&'\(\)\*\+,;=:@])|[\/\?])*)?)$/i
它们是如何编译的(在 PHP 中):
<?php
/* Regex convenience functions (character class, non-capturing group) */
function cc($str, $suffix = '', $negate = false)
return '[' . ($negate ? '^' : '') . $str . ']' . $suffix;
function ncg($str, $suffix = '')
return '(?:' . $str . ')' . $suffix;
/* Preserved from RFC3986 */
$ALPHA = 'a-z';
$DIGIT = '0-9';
$HEXDIG = $DIGIT . 'a-f';
$sub_delims = '!\\$&\'\\(\\)\\*\\+,;=';
$gen_delims = ':\\/\\?\\#\\[\\]@';
$reserved = $gen_delims . $sub_delims;
$unreserved = '-' . $ALPHA . $DIGIT . '\\._~';
$pct_encoded = '%' . cc($HEXDIG) . cc($HEXDIG);
$dec_octet = ncg(implode('|', array(
cc($DIGIT),
cc('1-9') . cc($DIGIT),
'1' . cc($DIGIT) . cc($DIGIT),
'2' . cc('0-4') . cc($DIGIT),
'25' . cc('0-5')
)));
$IPv4address = $dec_octet . ncg('\\.' . $dec_octet, '3');
$h16 = cc($HEXDIG, '1,4');
$ls32 = ncg($h16 . ':' . $h16 . '|' . $IPv4address);
$IPv6address = ncg(implode('|', array(
ncg($h16 . ':', '6') . $ls32,
'::' . ncg($h16 . ':', '5') . $ls32,
ncg($h16, '?') . '::' . ncg($h16 . ':', '4') . $ls32,
ncg($h16 . ':' . $h16, '?') . '::' . ncg($h16 . ':', '3') . $ls32,
ncg(ncg($h16 . ':', '0,2') . $h16, '?') . '::' . ncg($h16 . ':', '2') . $ls32,
ncg(ncg($h16 . ':', '0,3') . $h16, '?') . '::' . $h16 . ':' . $ls32,
ncg(ncg($h16 . ':', '0,4') . $h16, '?') . '::' . $ls32,
ncg(ncg($h16 . ':', '0,5') . $h16, '?') . '::' . $h16,
ncg(ncg($h16 . ':', '0,6') . $h16, '?') . '::',
)));
$IPvFuture = 'v' . cc($HEXDIG, '+') . cc($unreserved . $sub_delims . ':', '+');
$IP_literal = '\\[' . ncg(implode('|', array($IPv6address, $IPvFuture))) . '\\]';
$port = cc($DIGIT, '*');
$scheme = cc($ALPHA) . ncg(cc('-' . $ALPHA . $DIGIT . '\\+\\.'), '*');
/* New or changed in RFC3987 */
$iprivate = '\xE000-\xF8FF\xF0000-\xFFFFD\x100000-\x10FFFD';
$ucschar = '\xA0-\xD7FF\xF900-\xFDCF\xFDF0-\xFFEF' .
'\x10000-\x1FFFD\x20000-\x2FFFD\x30000-\x3FFFD' .
'\x40000-\x4FFFD\x50000-\x5FFFD\x60000-\x6FFFD' .
'\x70000-\x7FFFD\x80000-\x8FFFD\x90000-\x9FFFD' .
'\xA0000-\xAFFFD\xB0000-\xBFFFD\xC0000-\xCFFFD' .
'\xD0000-\xDFFFD\xE1000-\xEFFFD';
$iunreserved = '-' . $ALPHA . $DIGIT . '\\._~' . $ucschar;
$ipchar = ncg($pct_encoded . '|' . cc($iunreserved . $sub_delims . ':@'));
$ifragment = ncg($ipchar . '|' . cc('\\/\\?'), '*');
$iquery = ncg($ipchar . '|' . cc($iprivate . '\\/\\?'), '*');
$isegment_nz_nc = ncg($pct_encoded . '|' . cc($iunreserved . $sub_delims . '@'), '+');
$isegment_nz = ncg($ipchar, '+');
$isegment = ncg($ipchar, '*');
$ipath_empty = '(?!' . $ipchar . ')';
$ipath_rootless = ncg($isegment_nz) . ncg('\\/' . $isegment, '*');
$ipath_noscheme = ncg($isegment_nz_nc) . ncg('\\/' . $isegment, '*');
$ipath_absolute = '\\/' . ncg($ipath_rootless, '?'); // Spec says isegment-nz *( "/" isegment )
$ipath_abempty = ncg('\\/' . $isegment, '*');
$ipath = ncg(implode('|', array(
$ipath_abempty,
$ipath_absolute,
$ipath_noscheme,
$ipath_rootless,
$ipath_empty
))) . ')';
$ireg_name = ncg($pct_encoded . '|' . cc($iunreserved . $sub_delims . '@'), '*');
$ihost = ncg(implode('|', array($IP_literal, $IPv4address, $ireg_name)));
$iuserinfo = ncg($pct_encoded . '|' . cc($iunreserved . $sub_delims . ':'), '*');
$iauthority = ncg($iuserinfo . '@', '?') . $ihost . ncg(':' . $port, '?');
$irelative_part = ncg(implode('|', array(
'\\/\\/' . $iauthority . $ipath_abempty . '',
'' . $ipath_absolute . '',
'' . $ipath_noscheme . '',
'' . $ipath_empty . ''
)));
$irelative_ref = $irelative_part . ncg('\\?' . $iquery, '?') . ncg('\\#' . $ifragment, '?');
$ihier_part = ncg(implode('|', array(
'\\/\\/' . $iauthority . $ipath_abempty . '',
'' . $ipath_absolute . '',
'' . $ipath_rootless . '',
'' . $ipath_empty . ''
)));
$absolute_IRI = $scheme . ':' . $ihier_part . ncg('\\?' . $iquery, '?');
$IRI = $scheme . ':' . $ihier_part . ncg('\\?' . $iquery, '?') . ncg('\\#' . $ifragment, '?');
$IRI_reference = ncg($IRI . '|' . $irelative_ref);
2011 年 3 月 7 日编辑:由于 PHP 处理带引号的字符串中的反斜杠的方式,默认情况下这些是不可用的。您需要对反斜杠进行双重转义,除非反斜杠在正则表达式中具有特殊含义。你可以这样做:
$escape_backslash = '/(?<!\\)\\(?![\[\]\\\^\$\.\|\*\+\(\)QEnrtaefvdwsDWSbAZzB1-9GX]|x\[0-9a-f]1,4\|\c[A-Z]|)/';
$absolute_IRI = preg_replace($escape_backslash, '\\\\', $absolute_IRI);
$IRI = preg_replace($escape_backslash, '\\\\', $IRI);
$IRI_reference = preg_replace($escape_backslash, '\\\\', $IRI_reference);
【讨论】:
如果您认为这很糟糕,您应该查看电子邮件:ex-parrot.com/~pdw/Mail-RFC822-Address.html @Gumbo,它在规范中被允许并用于 HTTP 应用程序的 URI 实现。不鼓励(出于显而易见的原因)但完全有效,应该预料到。大多数(如果不是全部?)浏览器有时会将 HTTP 身份验证转换为 URL 以供后续访问。 @Devin,在什么语言的函数中?我用 PHP 编译它,但它可以在其他语言中使用。我应该用所有这些语言编写一个函数吗?或者,您也可以使用自己选择的语言来做同样的事情。 @joshcomley 将 \xABCD 替换为 \uABCD,如果你用 JS 编写的话 是的,http://com
是一个有效的 URL。 http://localhost
是,为什么不是其他词呢?您是正确的,u
修饰符在 PHP 中是必需的。我想明确一点,虽然我使用 PHP 生成了这些,但它们并不是特定于 PHP 的。【参考方案14】:
^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]1[a-z0-9]+)*\.[a-z]2,5(:[0-9]1,5)?(\/.*)?$
现场演示:https://regex101.com/r/HUNasA/2
我已经测试了各种表达式来满足我的要求。
作为用户,我可以使用以下字符串点击浏览器搜索栏:
有效的网址
https://www.google.com http://www.google.com http://google.com/ https://google.com/ www.google.com google.com https://www.google.com.ua http://www.google.com.ua http://google.com.ua https://google.com.ua/ www.google.com.ua google.com.ua https://mail.google.com http://mail.google.com mail.google.com无效的网址
http://google https://google.c 谷歌 谷歌。 .google .google.com goole.c ...【讨论】:
测试这个 URL:Google.com URL 应该不区分大小写 在 URL 的末尾放置空格,然后再次输入符号/字母,它将被视为 URL 的一部分 缩短和更正/^(http(s)?:\/\/)?(www.)?([a-zA-Z0-9])+([\-\.]1[a-zA-Z0-9]+)*\.[a-zA-Z]2,5(:[0-9]1,5)?(\/[^\s]*)?$/gm
regex101.com/r/KR2b6n/1
如果我用\b
替换^
和?
书挡,@AniNaslyan 的更正版本对我来说效果很好
localhost
呢?【参考方案15】:
https?:\/2(?:[\/-\w.]|(?:%[\da-fA-F]2))+
您可以使用此模式来检测 URL。
以下是概念证明
RegExr: URL Detector
【讨论】:
【参考方案16】:这是我制作的一个正则表达式,它从 URL 中提取不同的部分:
^((?:https?|ftp):\/\/?)?([^:/\s.]+\.[^:/\s]|localhost)(:\d+)?((?:\/\w+)*\/)?([\w\-.]+[^#?\s]+)?([^#]+)?(#[\w-]+)?$
((?:https?|ftp):\/\/?)?
(组 1):提取协议([^:/\s.]+\.[^:/\s]|localhost)
(组 2):提取主机名(:\d+)?
(group 3):提取端口号((?:\/\w+)*\/)?([\w\-.]+[^#?\s]+)?
(groups 4 & 5):提取路径部分([^#]+)?
(group 6 ):提取查询部分(#[\w-]+)?
(group 7):提取哈希部分
对于上面列出的正则表达式的每个部分,您可以删除结尾 ?
以强制它(或添加一个使其成为兼性)。您还可以删除正则表达式开头的^
和末尾的$
,这样就不需要匹配整个字符串。
在regex101 上查看。
注意:这个正则表达式不是 100% 安全的,它可能接受一些不一定是有效 URL 的字符串,但它确实验证了一些标准。它的主要目标是提取 URL 的不同部分而不是对其进行验证。
【讨论】:
谢谢。这些答案的小组方法是最好的。希望按照下一页链接的this article 的方向进行更新,并对“不是 100% 安全”进行修订。对于大多数读者来说,像 99.9% 这样的量化就足够了。 :P【参考方案17】:我刚刚写了一篇博文,介绍了一个很好的解决方案,可以识别大多数常用格式的 URL,例如:
www.google.com
http://www.google.com
mailto:somebody@google.com
somebody@google.com
www.url-with-querystring.com/?url=has-querystring
使用的正则表达式为:
/((([A-Za-z]3,9:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/
【讨论】:
那个也可以,但是它缺少对端口号的支持(在调试中很有用)。修改为/((([A-Za-z]3,9:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)/
这个正则表达式不处理带括号的链接:例如msdn.microsoft.com/en-us/library/ms563775(v=office.14).aspx
www后面的点不应该转义吗?
找到另一个匹配对象:width:210px;
和 margin:3px
不匹配“example.com”...?【参考方案18】:
现在这是一个相当古老的线程,问题要求使用基于正则表达式的 URL 验证器。我在寻找完全相同的东西时遇到了线程。虽然很可能编写一个非常全面的正则表达式来验证 URL。我最终选择了另一种做事的方式——使用 PHP 的 parse_url 函数。
如果无法解析 url,则返回布尔值 false。否则返回方案、主机等信息。这可能不足以单独进行全面的 URL 检查,但可以深入研究以进行进一步分析。如果目的是简单地捕捉拼写错误、无效方案等。这是完全足够的!
【讨论】:
【参考方案19】:有趣的是,上面的答案都不能满足我的需要,所以我想我会提供我的解决方案。我需要能够做到以下几点:
匹配http(s)://www.google.com
、http://google.com
、www.google.com
和google.com
匹配 Github markdown 风格的链接,如 [Google](http://www.google.com)
匹配所有可能的域扩展名,如 .com、.io 或 .guru 等。基本上是长度在 2-6 个字符之间的任何内容
将所有内容分成适当的分组,以便我可以根据需要访问每个部分。
解决方案如下:
/^(\[[A-z0-9 _]*\]\()?((?:(http|https):\/\/)?(?:[\w-]+\.)+[a-z]2,6)(\))?$
这给了我上述所有要求。如有必要,您可以选择添加 ftp 和文件功能:
/^(\[[A-z0-9 _]*\]\()?((?:(http|https|ftp|file):\/\/)?(?:[\w-]+\.)+[a-z]2,6)(\))?$
【讨论】:
【参考方案20】:非验证 URI 引用解析器
为了参考,这里是 IETF 规范:(TXT | HTML)。特别是,附录 B。解析使用正则表达式的 URI 引用演示了如何解析有效的正则表达式。这被描述为,
获取非验证 URI 引用解析器的示例,该解析器将采用任何给定字符串并提取 URI 组件。
这是他们提供的正则表达式:
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
正如其他人所说,最好将其留给您已经在使用的库/框架。
【讨论】:
完全没用。有人可以告诉我这个正则表达式 not 匹配的字符串吗? (“#?#?#”或“>>”都匹配。这些是什么类型的 URI?) @AlexD 不要向我抱怨。这是 URI 的官方规范。如果您不喜欢,请向 IETF 提出。 @AlexD 我认为这些可能被视为相对引用。请参阅 RFC 3986,第 4.2 节。 @andyg0808,你可能是对的,但事实仍然是这个正则表达式几乎可以匹配任何字符串。 根据问题,这不是一个好的答案,因为它没有验证。正在解析。这是两个不同的功能。如果你给这个正则表达式垃圾,它会尝试解析它。如果 URL 无效,则无法保证解析工作。【参考方案21】:我发现的最好的正则表达式是:/(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi
对于ios swift:(^|\\s)((https?:\\/\\/)?[\\w-]+(\\.[\\w-]+)+\\.?(:\\d+)?(\\/\\S*)?)
http://jsfiddle.net/9BYdp/1/
找到here
【讨论】:
【参考方案22】:经过严格的搜索,我最终确定了以下
^[a-zA-Z0-9]+\:\/\/[a-zA-Z0-9]+\.[-a-zA-Z0-9]+\.?[a-zA-Z0-9]+$|^[a-zA-Z0-9]+\.[-a-zA-Z0-9]+\.[a-zA-Z0-9]+$
这个东西在未来的 URL 中通用。
【讨论】:
【参考方案23】:希望对你有帮助……
^(http|https):\/\/+[\www\d]+\.[\w]+(\/[\w\d]+)?
【讨论】:
【参考方案24】:据我所知,这种表达方式对我来说很好-
(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]2,|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]2,|www\.[a-zA-Z0-9]\.[^\s]2,)
工作示例-
function RegExForUrlMatch()
var expression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]2,|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]2,|www\.[a-zA-Z0-9]\.[^\s]2,)/g;
var regex = new RegExp(expression);
var t = document.getElementById("url").value;
if (t.match(regex))
document.getElementById("demo").innerHTML = "Successful match";
else
document.getElementById("demo").innerHTML = "No match";
<input type="text" id="url" placeholder="url" onkeyup="RegExForUrlMatch()">
<p id="demo">Please enter a URL to test</p>
【讨论】:
【参考方案25】:这是RegexBuddy 的用途。
(\b(https?|ftp|file)://)?[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]
它与以下这些匹配(在** **
标记内):
**http://www.regexbuddy.com**
**http://www.regexbuddy.com/**
**http://www.regexbuddy.com/index.html**
**http://www.regexbuddy.com/index.html?source=library**
您可以通过 http://www.regexbuddy.com/download.html 下载 RegexBuddy。
【讨论】:
地鼠呢?可怜的被遗忘的地鼠。 您的正则表达式与我能想到的任何网址都不匹配 - 包括您提供的网址。我将您的正则表达式粘贴到 rubular.com 中,上面写着“必须转义正斜杠”。是否有错字,或者您可以通过在 rubular.com 上使用它来澄清吗? @PandaWood 那是因为你需要为 Ruby 格式化。 Ruby 的转义字符是什么? 作为 JavaScript RegExp 文字:/\b(https?|ftp|file):\/\/[\-A-Za-z0-9+&@#\/%?=~_|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_|]/
这几乎匹配所有东西......没用【参考方案26】:
这个怎么样:
^(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]2,|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]2,|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]\.[^\s]2,|www\.[a-zA-Z0-9]\.[^\s]2,)$
这些是测试用例:
你可以在here : https://regex101.com/r/mS9gD7/41试试看
【讨论】:
【参考方案27】:这不是正则表达式,但完成相同的事情(仅限 Javascript):
function isAValidUrl(url)
try
new URL(url);
return true;
catch(e)
return false;
【讨论】:
这个问题是 h ttp://bla 是一个有效的 URL(h 和 t 之间的空格所以不能使它成为一个实际的 URL)【参考方案28】:Getting parts of a URL (Regex) 帖子讨论了解析 URL 以识别其各种组件。如果你想检查一个 URL 是否格式正确,它应该足以满足你的需要。
如果您需要检查它是否真的有效,您最终将不得不尝试访问另一端的任何内容。
不过,一般而言,您最好使用由您的框架或其他库提供给您的函数。许多平台都包含解析 URL 的函数。例如,有 Python 的 urlparse 模块,在 .NET 中,您可以使用 System.Uri class's constructor 作为验证 URL 的方法。
【讨论】:
【参考方案29】:对我来说最好的 URL 正则表达式是:
"(([\w]+:)?//)?(([\d\w]|%[a-fA-F\d]2,2)+(:([\d\w]|%[a-fA-f\d]2,2)+)?@)?([\d\w][-\d\w]0,253[\d\w]\.)+[\w]2,4(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]2,2)*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]2,2)=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]2,2)*)?"
【讨论】:
这似乎受限于它可以接受的域数量? 谢谢!这是在 iOS 上为我工作的转义版本:(([\\w]+:)?//)?(([\\d\\w]|%[a-fA-f\\d]2,2)+(:([\\d\\w]|%[a-fA-f\\d]2,2)+)?@)?([\\d\\w][-\\d\\w]0,253[\\d\\w]\\.)+[\\w]2,4(:[\\d]+)?(/([-+_~.\\d\\w]|%[a-fA-f\\d]2,2)*)*(\\?(&?([-+_~.\\d\\w]|%[a-fA-f\\d]2,2)=?)*)?(#([-+_~.\\d\\w]|%[a-fA-f\\d]2,2)*)?
此正则表达式仅匹配最长 4 个字符的后缀,并且在 IP 地址(v4 和 v6)、本地主机和带有外来字符的域名上失败。我建议编辑您的包含大小范围,并至少将 \w
替换为 \pL
。
请注意,此 RegEx 不会捕获仅包含一个字母的子域的 URL,例如 "m.sitename.com"。为了解决这个问题,我不得不将([\d\w][-\d\w]0,253[\d\w]\.)+
更改为([\d\w][-\d\w]0,253[\d\w]?\.)+
(在它的末尾添加一个问号)
不适用于something.co.uk【参考方案30】:
要匹配一个 URL,有多种选择,这取决于您的要求。 以下是少数。
_(^|[\s.:;?\-\]<\(])(https?://[-\w;/?:@&=+$\|\_.!~*\|'()\[\]%#,☺]+[\w/#](\(\))?)(?=$|[\s',\|\(\).:;?\-\[\]>\)])_i
#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#iS
还有一个链接可以为您提供超过 10 种不同的 URL 验证变体。
https://mathiasbynens.be/demo/url-regex
【讨论】:
以上是关于检查字符串是不是为有效 URL 的最佳正则表达式是啥?的主要内容,如果未能解决你的问题,请参考以下文章