我正在使用下面的函数来匹配给定文本中的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='$1'>$1</a>"); 
}

当前回答

正确的URL检测与国际域名和星体字符支持不是微不足道的事情。Linkify-it库从许多条件构建正则表达式,最终大小约为6千字节:)。它比目前在公认答案中引用的所有lib都更准确。

看到linkify-it演示检查所有的边缘情况和测试你的。

如果需要链接HTML源代码,则应该首先解析它,然后分别迭代每个文本标记。

其他回答

识别URL很棘手,因为它们经常被标点符号包围,而且用户经常不使用URL的完整形式。有很多JavaScript函数可以用超链接替换url,但我在基于python的web框架Django中找不到一个像urlize过滤器一样好用的。因此,我将Django的urlize函数移植到JavaScript:

https://github.com/ljosa/urlize.js

一个例子:

urlize('Go to SO (stackoverflow.com) and ask. <grin>', 
       {nofollow: true, autoescape: true})
=> "Go to SO (<a href="http://stackoverflow.com" rel="nofollow">stackoverflow.com</a>) and ask. &lt;grin&gt;"

第二个参数如果为真,则会插入rel="nofollow"。如果第三个参数为真,则转义HTML中具有特殊含义的字符。请参阅README文件。

用链接替换url(一般问题的答案)

问题中的正则表达式漏掉了很多边缘情况。在检测URL时,最好使用专门的库来处理国际域名、新顶级域名(如.museum)、括号和URL内部和末尾的其他标点符号,以及许多其他边缘情况。有关其他问题的解释,请参阅Jeff Atwood的博客文章the Problem With url。

Dan Dascalescu的回答是URL匹配库的最佳总结 (截至2014年2月)


“使正则表达式替换多个匹配”(具体问题的回答)

在正则表达式的末尾添加一个“g”来启用全局匹配:

/ig;

但这只修复了正则表达式只替换第一个匹配的问题。不要使用那个代码。

/**
 * Convert URLs in a string to anchor buttons
 * @param {!string} string
 * @returns {!string}
 */

function URLify(string){
  var urls = string.match(/(((ftp|https?):\/\/)[\-\w@:%_\+.~#?,&\/\/=]+)/g);
  if (urls) {
    urls.forEach(function (url) {
      string = string.replace(url, '<a target="_blank" href="' + url + '">' + url + "</a>");
    });
  }
  return string.replace("(", "<br/>(");
}

简单的例子

我不得不做相反的事情,并使html链接只是URL,但我修改了你的正则表达式,它的工作就像一个魅力,谢谢:)

var exp = /<a\s.*href=['"](\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])['"].*>.*<\/a>/ig;

source = source.replace(exp,"$1");

用HTML链接替换文本中的url,忽略href/pre标记中的url。 https://github.com/JimLiu/auto-link