有个朋友问我一个在复杂文本中提取 URL 的正则表达式,在网上搜索了一下,鼓捣了好久,综合了多方资源,写出这么一个正则表达式:
(?<![a-zA-Z0-9://])((http|https|ftp):)?([A-Za-z0-9-]+/.)+[A-Za-z]{2,}(:[0-9]+)?[.//=/?%/-&_~`@[/]/':+!]*([^/"/"])*?(?![//=/?%/-&_~`@[/]/':+!A-Za-z0-9.])
加上点注释,我们来分析下:
(?<![a-zA-Z0-9://])(?#去掉左侧无用字符) ((http|https|ftp):)?(?#协议) ([A-Za-z0-9-]+/.)+(?#域名) [A-Za-z]{2,}(?#TLD) (:[0-9]+)?(?#端口号) [.//=/?%/-&_~`@[/]/':+!]*(?#分隔符) ([^/"/"])*?(?#网址) (?![//=/?%/-&_~`@[/]/':+!A-Za-z0-9.])(?#去掉右侧无用字符)
于是能看懂了么?
测试了些正常的 URL,都很正确。
- http://orzfly.com/
- http://orzfly:8080/orztech.php?tel=123456
- https://orzfly.com/
- http://www.williamlong.info/script/common.js
- relatedlinks.googlelabs.com/client/client.js?url=shcom&referrer=&relatedlinks_id=10065_599317151813484&title=
- ……
测试了些不正确的 URL:
- www.1/a.exe:没有匹配,正确。
- www.1@22.ci:没有匹配,正确。
- 123%ww.com:没有匹配,正确。
- www.煞笔.com:没有匹配,不正确。应该能匹配,但是由于支持国际域名难度较大,抛弃。
- www.a/b.cc:没有匹配,正确。
- g.cn/a/b.exe:没有匹配,正确。
- www.g.cnmmmg.cnlllhttp:123.123.123.123:80hhhwok.cshdn.comsdfsdf:能完整匹配,但是这个肯定不正确。求高人指点。