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

当前回答

应该注意关于URI复杂性的警告,但对您的问题的简单回答是: 要替换每个匹配项,你需要在RegEx的末尾添加/g标志: / (\ b (https ? | | ftp文件):\ / \ [-A-Z0-9 +&@#\/%?=~_|!:,.;]*[- A-Z0-9 +&@#\/%=~_|])/ 胃肠道

其他回答

如果你需要显示更短的链接(仅域),但具有相同的长URL,你可以尝试我对Sam Hasler的代码版本上面发布的修改

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

我还编写了另一个JavaScript库,它可能对您更好,因为它非常敏感,误报最少,速度快,规模小。我目前正在积极维护它,所以请在演示页面中测试它,看看它是如何为你工作的。

链接:https://github.com/alexcorvi/anchorme.js

应该注意关于URI复杂性的警告,但对您的问题的简单回答是: 要替换每个匹配项,你需要在RegEx的末尾添加/g标志: / (\ b (https ? | | ftp文件):\ / \ [-A-Z0-9 +&@#\/%?=~_|!:,.;]*[- A-Z0-9 +&@#\/%=~_|])/ 胃肠道

保持简单!说你不能拥有的,而不是你能拥有的。

如上所述,url可能相当复杂,特别是在'?',并不是所有的都以'www '开头,例如maps.bing.com/something?key=!"£$%^*()&lat=65&lon&lon=20

所以,与其有一个不满足所有边缘情况的复杂正则表达式,而且很难维护,不如用这个更简单的正则表达式,它在实践中对我来说很好。

匹配

http(s)://(除空格外的任何字符)+

www。(除了空格)+

Where 'anything' is [^'"<>\s] ... 基本上是一个贪婪匹配,在你遇到一个空格,引号,尖括号,或行尾

另外:

记得检查它是不是URL格式,例如文本包含href="…"或src="…"

添加ref=nofollow(如果合适的话)

这个解决方案不像上面提到的库那样“好”,但是要简单得多,并且在实践中工作得很好。

if html.match( /(href)|(src)/i )) {
    return html; // text already has a hyper link in it
    }

html = html.replace( 
            /\b(https?:\/\/[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='$1'>$1</a>" 
            );

html = html.replace( 
            /\s(www\.[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='http://$1'>$1</a>" 
            );

html = html.replace( 
             /^(www\.[^\s\(\)\'\"\<\>]+)/ig, 
            "<a ref='nofollow' href='http://$1'>$1</a>" 
            );

return html;

我对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="$1" target="_blank">$1</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, '$1<a href="http://$2" target="_blank">$2</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:$1">$1</a>');

    return replacedText;
}