我正在使用下面的函数来匹配给定文本中的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>");
}
上面Travitron回答中的电子邮件检测对我来说不起作用,所以我用下面的c#代码扩展/替换了它。
// 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:$1@$2.$3"">$1@$2.$3</a>";
text = Regex.Replace(text, pat3, rep3, o);
这允许像“firstname.secondname@one.two.three.co.uk”这样的电子邮件地址。
识别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. <grin>"
第二个参数如果为真,则会插入rel="nofollow"。如果第三个参数为真,则转义HTML中具有特殊含义的字符。请参阅README文件。
首先,滚动自己的regexp来解析url是一个糟糕的想法。您必须想象这是一个足够常见的问题,根据rfc,有人已经为它编写、调试和测试了一个库。URI是复杂的——查看Node.js中URL解析的代码和关于URI方案的维基百科页面。
在解析URL时,有大量的边缘情况:国际域名,实际的(.museum)和不存在的(.etc)顶级域名,奇怪的标点符号(包括括号),URL末尾的标点符号,IPV6主机名等。
我已经查看了大量的库,尽管有一些缺点,但还是有一些值得使用:
Soapbox的linkify已经投入了大量精力,2015年6月的一次重大重构删除了jQuery依赖项。它仍然存在idn问题。
AnchorMe是一个自称更快更精简的新产品。还有一些IDN问题。
Autolinker.js列出了非常具体的特性(例如:将正确处理HTML输入。该实用程序不会改变anchor()标签内的href属性”)。当演示版本可用时,我将对其进行一些测试。
我很快就取消了这个任务的库:
Django的urlize不能正确处理某些tld(以下是官方列出的有效tld)。没有演示。
autolink-js不会检测“www.google.com”没有http://,,所以它不太适合自动链接“随意的url”(没有方案/协议)在纯文本中找到。
本·阿尔曼的链接自2009年以来就没有维护过。
如果坚持使用正则表达式,最全面的是Component中的URL regexp,尽管它会错误地检测到一些不存在的双字母tld。