如何修改正则表达式以匹配字符串中的所有URL(含bing.com)
问题描述
我想用以下代码提取字符串中的所有URL,但目前只能匹配到http://www.google.com、https://www.twitter.com和www.msn.com这三个URL,无法匹配bing.com。请问该如何修改正则表达式?
function openURLs() { let links = "http://www.google.com Hello https://www.twitter.com The www.msn.com World bing.com"; if (links) { var expression = /(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,})/gi; var url_array = links.match(expression); if (url_array != null) { url_array.forEach((url) => { urlOK = url.match(/^https?:/) ? url : '//' + url; window.open(urlOK) }); } } }
修改方案
原正则的问题在于未覆盖不带www.前缀的裸域名(如bing.com),仅匹配了带协议、带www.的URL。只需在正则中新增一个分支,专门匹配这类裸域名即可。
修改后的正则表达式
var expression = /(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,}|[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,})/gi;
关键修改点
新增分支:[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}
- 该分支匹配无协议、无
www前缀的合法域名:要求域名主体以字母数字开头/结尾,中间可含连字符,后缀长度至少2位(如.com/.org),且域名后无空白字符。
完整修改后的代码
function openURLs() { let links = "http://www.google.com Hello https://www.twitter.com The www.msn.com World bing.com"; if (links) { // 添加裸域名匹配分支 var expression = /(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,}|[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,})/gi; var url_array = links.match(expression); if (url_array != null) { url_array.forEach((url) => { urlOK = url.match(/^https?:/) ? url : '//' + url; window.open(urlOK) }); } } }
可选优化
若需要匹配x.com这类单字符主体的极简域名,可将新增分支改为:[a-zA-Z0-9]+\.[^\s]{2,}。
内容的提问来源于stack exchange,提问作者HelloCW
相关产品推荐
相关产品推荐

