arrayOfStrings.forEach(function(string){
// detect URLs in strings and do something swell,
// like creating elements with links.
});
完整的帮助程序(带有可选的车把支持)位于要点1654670。
#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 = $('
–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/linkifyjsLinkify是一个小而全面的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-regex
或npm 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.innerHTMLfunction 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
评论
尝试列出有限的TLD可能不是一个好主意,因为它们会不断创建新的TLD。同意。有时我们需要的是带有TLD的可更新代码。实际上可以通过构建脚本将TLD附加到正则表达式中,也可以通过动态代码更新TLD。生活中的某些事物要像TLD和Timezone这样要标准化。有限的控制对于验证真实世界地址用例的现有“ TLD”可验证URL可能是不错的选择。