【问题标题】:How to replace URLs not within a href tag in javascript如何在javascript中替换不在href标签内的URL
【发布时间】:2013-02-06 14:11:55
【问题描述】:

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

  1. www.stackoverflow.com
  2. 堆栈溢出

我正在尝试创建一个使用正则表达式的简单函数,该函数将使用 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 回答的帮助下修复它的解决方案

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>';
        }
    });
}

【问题讨论】:

  • @Dve 并不是真正的重复。我试图仅在纯 URL 未用 href 标记包装的情况下用链接替换纯 URL。因为我在 HTML 文档上执行此操作。另一个正则表达式实际上完全失败了我的测试用例。

标签: javascript regex regex-negation


【解决方案1】:

在不尝试分析上面复杂的正则表达式和函数的情况下,这里是一个使用玩具 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* 根据需要。

【讨论】:

  • 不错的解决方案,这有效并替换了字符串上的所有链接(并忽略了已经链接的链接)。不过,我必须让它在 URL 前加上 http://,否则链接会被破坏。
【解决方案2】:

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

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

【讨论】:

  • 核心要求是避免匹配那些已经链接的网址。我没有看到这里提到的。
  • 正则表达式要求输入以空格或换行符结尾。
  • 我没有注意到这一点。但是,这似乎不是一种非常可靠的处理方式。 URL 后跟标点符号、右括号等呢?最好使用否定的后视来确保它不是链接(或者更好的是,将 HTML 解析器与正则表达式结合使用)。
  • @dan1111 但是javascript支持落后了吗?
  • 这行得通,但它只匹配我的测试字符串中的第一个链接。
猜你喜欢
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 2013-09-05
  • 1970-01-01
  • 2011-09-14
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多