5

我有一个包含 URL 链接的文本的情况。链接有两种形式

  1. www.stackoverflow.com
  2. <a href="http://www.stackoverflow.com">堆栈溢出</a>

我正在尝试创建一个使用正则表达式的简单函数,该函数将使用 A HREF 标记包装类型1的所有链接,但让其他链接已经单独包装。

我有类似的东西,但没有成功。

function replaceURLWithHTMLLinks(text) {
    var exp = /(<(\s*)a(\s)*href.*>.*<\/(\s)*a(\s*)>)/ig;
    var matches = exp.exec(text);
    for(var i=0; i < matches.length; i++) {
        var line = matches[i];
        if(!exp.test(line)) {
            var exp2 = /(\b(?:(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[-A-Z0-9+&@#\/%=~_|$])|”(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[^"\r\n]+”?|’(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[^'\r\n]+’?)/ig;
            text = text.replace("http://","");
                text = text.replace(exp2, "<a href=http://$1>$1</a>");
        }
    }

    return text;
}

它不起作用,但希望有人可以修复它:)

编辑

在@MikeM answer的帮助下修复它的解决方案

function replaceLinksSO(text) {
    rex = /(<a href=")?(?:https?:\/\/)?(?:(?:www)[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+\.)+[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+/ig;   
    return text.replace(rex, function ( $0, $1 ) {
        if(/^https?:\/\/.+/i.test($0)) {
            return $1 ? $0: '<a href="'+$0+'">'+$0+'</a>';
        }
        else {
            return $1 ? $0: '<a href="http://'+$0+'">'+$0+'</a>';
        }
    });
}
4

2 回答 2

5

在不尝试分析上面复杂的正则表达式和函数的情况下,这里是一个使用玩具 url 匹配模式的示例实现来说明进行此类替换的方法

var str = ' www.stackoverflow.com  <a href="http://www.somesite.com">somesite</a> www.othersite.org '
    rex = /(<a href=")?(?:https?:\/\/)?(?:\w+\.)+\w+/g;    

str = str.replace( rex, function ( $0, $1 ) {
    return $1 ? $0 : '<a href="' + $0 + '">' + $0 + '</a>';
});

您可以更改 url 匹配模式并\s*根据需要插入例如。

于 2013-02-21T10:38:35.813 回答
1

替换匹配/(https?:\/\/)?((?:www|ftp)\.[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+?)[\r\n\s]+/的模式<a href="$1$2">$1</a>将满足您的要求。

一个更好的正则表达式匹配将是^(?!href="[^"\n\r\s]+?").*?(https?:\/\/)?((?:www|ftp)\.[-A-Za-z0-9+&@#\/%?=~_|$!:,.;]+)$

于 2013-02-21T10:26:19.917 回答