有没有人建议检测一组字符串中的URL? >
arrayOfStrings.forEach(function(string){
  // detect URLs in strings and do something swell,
  // like creating elements with links.
});


完整的帮助程序(带有可选的车把支持)位于要点1654670。

评论

尝试列出有限的TLD可能不是一个好主意,因为它们会不断创建新的TLD。

同意。有时我们需要的是带有TLD的可更新代码。实际上可以通过构建脚本将TLD附加到正则表达式中,也可以通过动态代码更新TLD。生活中的某些事物要像TLD和Timezone这样要标准化。有限的控制对于验证真实世界地址用例的现有“ TLD”可验证URL可能是不错的选择。

#1 楼

首先,您需要一个与网址匹配的优质正则表达式。这很难做到。请参见此处,此处和此处:


...几乎所有内容都是有效的URL。对于
,有一些标点符号规则将其拆分。缺少任何
标点符号,您仍然有一个有效的
URL。

请仔细检查RFC,看看您是否可以构造“无效的” URL。
规则非常灵活。

例如:::::是有效的URL。
路径是":::::"。漂亮的
愚蠢的文件名,但是有效的文件名。

另外,/////是有效的URL。
netloc(“主机名”)是""。路径
"///"。再次,愚蠢。同样有效。此URL规范化为"///"
,这是等效的。

"bad://///worse/////"
这样的东西是完全有效的。愚蠢但有效。


无论如何,此答案并不意味着为您提供最佳的正则表达式,而是证明如何使用JavaScript在文本中进行字符串换行。

好,所以我们就使用它:/(https?:\/\/[^\s]+)/g

同样,这是一个不好的正则表达式。它将有许多误报。但是,对于此示例来说已经足够了。




 function urlify(text) {
  var urlRegex = /(https?:\/\/[^\s]+)/g;
  return text.replace(urlRegex, function(url) {
    return '<a href="' + url + '">' + url + '</a>';
  })
  // or alternatively
  // return text.replace(urlRegex, '<a href=""></a>')
}

var text = 'Find me at http://www.example.com and also at http://stackoverflow.com';
var html = urlify(text);

console.log(html) 





// html now looks like:
// "Find me at <a href="http://www.example.com">http://www.example.com</a> and also at <a href="http://stackoverflow.com">http://stackoverflow.com</a>"


因此,总之尝试:

$$('#pad dl dd').each(function(element) {
    element.innerHTML = urlify(element.innerHTML);
});


评论


“许多误报”的一些示例将大大改善此答案。否则,未来的Google员工将只剩下一些(也许有效?)FUD。

–cmcculloh
2014年7月23日下午2:41

我不知道您可以将功能作为.replace的第二个参数传递给您:

– Aamir Afridi
15年6月17日在15:44

很好,但是在结尾标点符号text =“在http://www.example.com上以及在http://stackoverflow.com上找到我”上也做错了事。结果是两个404。一些用户已经意识到这一点,并且会在标点符号之前在URL后面添加一个空格以避免损坏,但是我使用的大多数链接符(Gmail,etherpad,phabricator)都将单独的尾随标点符号与URL分开。

–skierpage
15年7月30日在19:01

如果文本已经包含锚定网址,则可以使用函数removeAnchors(text){var div = $('
')。html(text); div.find('a')。contents()。unwrap();返回div.text();返回文本之前先删除锚点。

–Muneeb Mirza
18年11月27日在8:22

如果文本已经包含锚定的URL,则您正在使用jquery删除锚定,但是我正在使用Angular。如何在Angular中删除锚点?

– Sachin Jagtap
19年5月2日在7:44

#2 楼

这是我最终用作正则表达式的内容:

var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;


这不包括URL中的结尾标点符号。 Crescent的功能就像一个魅力一样:)
so:

function linkify(text) {
    var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
    return text.replace(urlRegex, function(url) {
        return '<a href="' + url + '">' + url + '</a>';
    });
}


评论


最后,一个正则表达式在最明显的情况下确实有效!这个值得一书签。我测试了Google搜索中的数千个示例,直到找到了。

–伊斯梅尔
2015年1月16日15:11

简单又漂亮!但是urlRegex应该在linkify之外定义,因为编译起来很昂贵。

– B M
17年8月19日在19:22

这无法检测完整的URL:disney.wikia.com/wiki/Pua_(Moana)

– Jry9972
17年12月14日在11:07

我在每个字符列表中添加了(),现在可以使用了。

– Guillaume F.
18年3月21日在1:06

它无法检测到仅以www开头的网址。例如:www.facebook.com

– CraZyDroiD
18-10-11在4:44

#3 楼

我在这个问题上搜索了很长时间,然后发现我有一个Android方法android.text.util.Linkify,它利用一些非常强大的正则表达式来完成此任务。幸运的是,Android是开源的。

它们使用几种不同的模式来匹配不同类型的url。您可以在这里找到所有这些文件:
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/text/util/Regex。 java#Regex.0WEB_URL_PATTERN

如果您只关心与WEB_URL_PATTERN匹配的URL,即符合RFC 1738规范的URL,则可以使用以下命令: >
/((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi;


以下是源代码的全文:也一样电子邮件地址的正则表达式为:

"((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)"
+ "\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_"
+ "\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?"
+ "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+"   // named host
+ "(?:"   // plus top level domain
+ "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
+ "|(?:biz|b[abdefghijmnorstvwyz])"
+ "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
+ "|d[ejkmoz]"
+ "|(?:edu|e[cegrstu])"
+ "|f[ijkmor]"
+ "|(?:gov|g[abdefghilmnpqrstuwy])"
+ "|h[kmnrtu]"
+ "|(?:info|int|i[delmnoqrst])"
+ "|(?:jobs|j[emop])"
+ "|k[eghimnrwyz]"
+ "|l[abcikrstuvy]"
+ "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])"
+ "|(?:name|net|n[acefgilopruz])"
+ "|(?:org|om)"
+ "|(?:pro|p[aefghklmnrstwy])"
+ "|qa"
+ "|r[eouw]"
+ "|s[abcdeghijklmnortuvyz]"
+ "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
+ "|u[agkmsyz]"
+ "|v[aceginu]"
+ "|w[fs]"
+ "|y[etu]"
+ "|z[amw]))"
+ "|(?:(?:25[0-5]|2[0-4]" // or ip address
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]"
+ "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1]"
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
+ "|[1-9][0-9]|[0-9])))"
+ "(?:\:\d{1,5})?)" // plus option port number
+ "(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~"  // plus option query params
+ "\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?"
+ "(?:\b|$)";


PS:上述正则表达式支持的顶级域是截至2007年6月的最新域名。有关最新列表,您将需要检查https://data.iana.org/TLD/tlds-alpha-by-domain.txt。

评论


由于您使用不区分大小写的正则表达式,因此无需指定a-zA-Z和http | https | Http | Https | rtsp | Rtsp。

–Ry-♦
2013年12月5日,下午3:06

很好,但是我不确定我是否会使用它。对于大多数用例,我宁愿接受一些误报,而不是使用依赖于TLD硬编码列表的方法。如果在代码中列出了TLD,则可以保证有一天会过时,如果可以避免的话,我宁愿不对代码进行将来的强制性维护。

–马克·阿默里(Mark Amery)
15年3月29日在11:10

这项工作有101%的时间有效,但不幸的是,它还会找到没有空格的URL。如果我在hello@mydomain.com上进行匹配,则会捕获“ mydomain.com”。有没有一种方法可以改进它,使其仅在其前面有空格的情况下才能捕获?

–Deminetix
2015年3月31日5:03



还要注意,这非常适合捕获用户输入的网址

–Deminetix
15年3月31日在5:04

请注意,grepcode.com不再可用,我认为这是指向Android源代码中正确位置的链接。我认为Android使用的regex可能自2013年起更新(原始帖子),但自2015年以来似乎未更新,因此可能缺少一些较新的TLD。

–詹姆斯
19/12/18在19:01



#4 楼

如果您想检测带有http://或不带http://以及www的链接,请基于Crescent Fresh答案。您可以使用以下

function urlify(text) {
    var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g;
    //var urlRegex = /(https?:\/\/[^\s]+)/g;
    return text.replace(urlRegex, function(url,b,c) {
        var url2 = (c == 'www.') ?  'http://' +url : url;
        return '<a href="' +url2+ '" target="_blank">' + url + '</a>';
    }) 
}


评论


这是一个很好的解决方案,但我也想检查文本是否不应该包含href。我尝试过此正则表达式= /((?!href)((https?:\/\/)|(www\.)|(mailto:))[^\s]+)/gi,但它不起作用。您能为我提供帮助吗,还是上述正则表达式为何不起作用?

– Sachin Jagtap
19年5月2日在6:26



我喜欢您还向返回的输出中添加了target =“ _ blank”。这个版本是我想要的。没有什么可以超过大多数链接的顶部(否则我会使用Linkifyjs)。

–迈克尔·库伯勒
19年11月28日在10:35

#5 楼

NPM上的该库看起来非常全面https://www.npmjs.com/package/linkifyjs


Linkify是一个小而全面的JavaScript插件,用于查找纯文本URL并将其转换为HTML链接。它适用于所有有效的URL和电子邮件地址。


评论


我刚刚在项目中实现了linkifyjs,这太棒了。 Linkifyjs应该是这个问题的答案。另一个要看的是github.com/twitter/twitter-text

–Uber Schnoz
17年6月1日在20:08

#6 楼

还可以进一步改善功能以渲染图像:

function renderHTML(text) { 
    var rawText = strip(text)
    var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   

    return rawText.replace(urlRegex, function(url) {   

    if ( ( url.indexOf(".jpg") > 0 ) || ( url.indexOf(".png") > 0 ) || ( url.indexOf(".gif") > 0 ) ) {
            return '<img src="' + url + '">' + '<br/>'
        } else {
            return '<a href="' + url + '">' + url + '</a>' + '<br/>'
        }
    }) 
} 


,或者链接到完整尺寸图像的缩略图:

return '<a href="' + url + '"><img style="width: 100px; border: 0px; -moz-border-radius: 5px; border-radius: 5px;" src="' + url + '">' + '</a>' + '<br/>'


这是strip()函数,它通过删除任何现有的html来预处理文本字符串,以确保一致性。

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerText.replace(urlRegex, function(url) {     
        return '\n' + url 
    })
} 


#7 楼

现有npm软件包:url-regex,只需将其与yarn add url-regexnpm install url-regex一起安装并按以下方式使用:

const urlRegex = require('url-regex');

const replaced = 'Find me at http://www.example.com and also at http://stackoverflow.com or at google.com'
  .replace(urlRegex({strict: false}), function(url) {
     return '<a href="' + url + '">' + url + '</a>';
  });


#8 楼

let str = 'https://example.com is a great site'
str.replace(/(https?:\/\/[^\s]+)/g,"<a href='' target='_blank' ></a>")


短代码大工作!...

结果:-

 <a href="https://example.com" target="_blank" > https://example.com </a>


#9 楼

试试这个:

#10 楼

面向对象的通用解决方案

对于像我这样使用不允许直接操作DOM的angular框架的人,我创建了一个函数,该函数接受字符串并返回一个数组url / plainText可以用于创建所需的任何UI表示形式。函数还会从h0mayun/(?:(?:https?:\/\/)|(?:www\.))[^\s]+/g之类的URL末尾删除标点符号,我相信它比实际的URL结尾更经常是实际的标点符号(但可能是这样!这并不严格,因为其他答案很好地解释了这一点)将以下正则表达式添加到匹配的网址.上。

#11 楼

如果要使用http://或不使用http://或ftp或其他可能的情况(例如最后删除结尾的标点符号)来检测链接,请查看以下代码。

https:// jsfiddle.net/AndrewKang/xtfjn8g3/

一种简单的使用方法是使用NPM

npm install --save url-knife


#12 楼

tmp.innerText未定义。您应该使用tmp.innerHTML

function strip(html) 
    {  
        var tmp = document.createElement("DIV"); 
        tmp.innerHTML = html; 
        var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;   
        return tmp.innerHTML .replace(urlRegex, function(url) {     
        return '\n' + url 
    })


#13 楼

您可以使用这样的正则表达式来提取普通的网址格式。 > https://www.npmjs.com/package/pattern-dreamer

评论


(?:www \。||(?!www))的目的是什么?为什么wwwww.com无效?

–多多
19年7月5日在9:31

你是对的。实际上,我只是把它当作正则表达式使用了。我建议使用上面的链接库。在网址检测中我们应该考虑很多情况,因此正则表达式应该更复杂。

–康·安德鲁
19年7月8日在5:56