网上流传着多种匹配URL的正则表达式版本,但我经过试验,最好用的还是从stackoverflow上查到的: (https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|] IP地址、前后有汉字、带参数的,都是OK的。 另外几个有问题的版本:摘自微软MSDN:(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)? 带参数的匹配有问题。 百度知道中有人回答的:http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)? 有严重的汉字问题。 另外,如果只是想匹配URL中的域名部分,则可以用这个:((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(:[0-9]+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?) 看不懂正则表达式?用regulex试试,可以把正则表达式可视化! 参考:精通正则表达式的 12 个有用资源 你可能需要准确地知道一段字符串是否是域名/网址/URL。虽然可以使用 实际上单纯使用正则表达式来精确匹配也是非常复杂的,通过代码来判断会简单很多。不过本文依然从域名的定义出发来尽可能匹配一段字符串是否是域名或者网址,在要求不怎么高的场合,使用本文的正则表达式写的代码会比较简单。 网址网址实际上是 URL(统一资源定位符),它是由协议、主机名和路径组成。不过我们通常所说的网址中的主机名通常是域名,因此我们在匹配的时候主要考虑域名。 域名维基百科 中关于域名的描述:
后面关于非 ASCII 字符的描述我没有贴出来。这种域名例如“.中国”。 在 中国电信网站备案自助管理系统 中,我们可以找到关于域名的描述:
路径路径是使用
正则表达式匹配在确认了完整的网址 URL 的规范之后,使用正则表达式来匹配就会比较精确了。 域名现在,我们来尝试匹配一下域名 。
别忘了,我们还有总长度限制,于是考虑加上零宽断言 现在,把整个正则表达式拼出来:
URL对于不同的业务需求,可能有严格匹配或者宽松的匹配方式。 比如你要做一些比较精准的检查时需要进行严格的检查,那么选择严格匹配;这时,稍微出现一些不符合要求的字符都将认定为不是 URL。 如果你只是打算做一些简单的检查(例如只是语法高亮),那么简单匹配即可;因为当你使用 Chrome 浏览器访问这些 URL 的时候,依然可以正常访问,Chrome 会帮你格式化一下这个 URL。
URL(严格)匹配 URL 跟匹配域名不一样,URL 复杂得多。严格匹配的要求是准确反应出 URL 的标准,但实际上如实反应标准编写的正则表达式会非常复杂,因此相比于 100% 准确匹配,我们还是从简了。 所以如果不是有特别要求,建议还是跳到后面的“宽松”部分来阅读吧! 我们以下面这个网址为例说明。 https://blog.walterlv.com/post/read-32bit-registry-from-x64-process.html
组合整个正则表达式:
顺便一提,不同于域名,我们这里去掉了长度限制,因为 URL 真的可以“很长”。另外,这里的 现在,我们补充说明一下资源路径可以使用的字符问题。
因此,我们最终总结应该匹配的特殊字符有 URL(宽松)宽松一点的话,正则表达式就好写多了。 这个正则表达式可以不写
如果上下文中要求必须匹配
这里的宽松正则表达式请小心!此正则表达式会将一段话中 URL 后面非空格的部分都算作 URL 的一部分。 更多大牛匹配 URL 的正则表达式在 GitHub 上还有很多大牛们在写各种匹配 URL 的正则表达式:
最长的一个写了 1347 个字符,最短的有 38 个字符。 有人将其整理成一张表格,一图说明各种正则表达式能匹配到什么程度:
参考资料
本文会经常更新,请阅读原文: https://blog.walterlv.com/post/match-web-url-using-regex.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。 |