如何用链接替换纯URL?
我正在使用下面的功能来匹配给定文本内的URL,并将其替换为HTML链接。正则表达式效果很好,但目前我仅替换第一个匹配项。
如何替换所有URL?我想我应该使用exec命令,但是我没有真正弄清楚该怎么做。
function replaceURLWithHTMLLinks(text) { var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/i; return text.replace(exp,"<a href=''></a>"); }
解决方案
回答
用链接替换URL(常见问题的答案)
问题中的正则表达式遗漏了很多边缘情况。检测URL时,最好使用专门的库来处理国际域名,URL内和末尾的新.TLD(如.museum),括号和其他标点符号以及许多其他边缘情况。有关其他一些问题的说明,请参见Jeff Atwood的博客文章" URL的问题"。
The best summary of URL matching libraries is in Dan Dascalescu's Answer (as of Feb 2014)
"使一个正则表达式替换多个匹配项"(针对特定问题的答案)
在正则表达式的末尾添加" g"以启用全局匹配:
/ig;
但这仅解决了正则表达式仅替换第一个匹配项的问题。不要使用该代码。
回答
我不得不做相反的事情,并且使HTML链接仅进入URL,但是我修改了正则表达式,它的工作原理很吸引人,谢谢:)
var exp = /<a\s.*href=['"](\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])['"].*>.*<\/a>/ig; source = source.replace(exp,"");
回答
谢谢,这是非常有帮助的。我还希望可以链接看起来像URL的东西-作为基本要求,即使没有http://协议前缀,它也可以链接www.yahoo.com之类的东西。所以基本上,如果是" www。"存在,它将链接它并假定它是http://。我还希望电子邮件能够转变为mailto:链接。示例:www.yahoo.com将转换为www.yahoo.com
这是我最终得到的代码(此页面的代码与我在网上找到的其他内容以及我自己完成的其他内容的组合):
function Linkify(inputText) { //URLs starting with http://, https://, or ftp:// var replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; var replacedText = inputText.replace(replacePattern1, '<a href="" target="_blank"></a>'); //URLs starting with www. (without // before it, or it'd re-link the ones done above) var replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; var replacedText = replacedText.replace(replacePattern2, '<a href="http://" target="_blank"></a>'); //Change email addresses to mailto:: links var replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim; var replacedText = replacedText.replace(replacePattern3, '<a href="mailto:"></a>'); return replacedText }
在第二次替换中,如果(^ | [^ /])部分尚未以//开头,则仅替换www.whatever.com--如果在第一次替换中已经链接了URL,则避免双重链接。同样,www.whatever.com可能位于字符串的开头,这是正则表达式中该部分的第一个"或者"条件。
可以将其集成为jQuery插件,如上面的Jesse P所示-但我特别想要一个不作用于现有DOM元素的常规函数,因为我要获取已有的文本,然后将其添加到DOM中,希望在添加文本之前先对其进行"链接化",所以我通过此函数传递了文本。效果很好。
回答
Travitron上面的答案中的电子邮件检测对我而言不起作用,因此我用以下代码(Ccode)对其进行了扩展/替换。
// Change e-mail addresses to mailto: links. const RegexOptions o = RegexOptions.Multiline | RegexOptions.IgnoreCase; const string pat3 = @"([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,6})"; const string rep3 = @"<a href=""mailto:@."">@.</a>"; text = Regex.Replace(text, pat3, rep3, o);
这允许使用电子邮件地址,例如" [email protected]"。
回答
最好的脚本来做到这一点:
http://benalman.com/projects/javascript-linkify-process-lin/
回答
我对Travis的代码做了一些小的修改(只是为了避免任何不必要的重新声明,但这对我的需求非常有用,太好了!):
function linkify(inputText) { var replacedText, replacePattern1, replacePattern2, replacePattern3; //URLs starting with http://, https://, or ftp:// replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; replacedText = inputText.replace(replacePattern1, '<a href="" target="_blank"></a>'); //URLs starting with "www." (without // before it, or it'd re-link the ones done above). replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; replacedText = replacedText.replace(replacePattern2, '<a href="http://" target="_blank"></a>'); //Change email addresses to mailto:: links. replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim; replacedText = replacedText.replace(replacePattern3, '<a href="mailto:"></a>'); return replacedText; }