代码之家  ›  专栏  ›  技术社区  ›  moie

将字符串中的URL替换为链接元素

  •  0
  • moie  · 技术社区  · 3 年前

    我使用下面的函数来匹配给定文本中的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>"); 
    }
    
    0 回复  |  直到 13 年前
        1
  •  8
  •   Zuhair Taha    6 年前

    首先,滚动您自己的regexp来解析URL是一个 糟糕的想法 。你必须想象这是一个足够常见的问题,有人已经编写、调试和 tested 根据 the RFCs URI很复杂 -查看 code for URL parsing in Node.js 和上的维基百科页面 URI schemes

    在解析URL时,有很多边缘情况: international domain names ,实际( .museum )与不存在( .etc )TLD,奇怪的标点符号包括 parentheses ,URL末尾的标点符号,IPV6主机名等。

    我看过 a ton 属于 libraries ,尽管有一些缺点,但仍有一些值得使用:

    我很快取消了执行此任务资格的库:

    如果你坚持使用正则表达式,最全面的是 URL regexp from Component ,尽管通过查看它会错误地检测到一些不存在的两个字母的TLD。

        2
  •  3
  •   Moonis Abidi    6 年前

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

    问题中的正则表达式未命中 很多 边缘案例。在检测URL时,最好使用专门的库来处理国际域名,比如新的TLD .museum 、括号和URL内和末尾的其他标点符号,以及许多其他边缘大小写。查看Jeff Atwood的博客文章 The Problem With URLs 以了解其他一些问题的解释。

    这个 URL匹配库的最佳摘要 在中 Dan Dascalescu's Answer +100
    (截至2014年2月)


    “使正则表达式替换多个匹配项”(特定问题的答案)

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

    /ig;
    

    但这只解决了正则表达式只替换第一个匹配项的问题。 不要使用该代码。

        3
  •  1
  •   Rahul Hirve    6 年前

    我对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;
    }
    
        4
  •  0
  •   Danial Nazari    4 年前

    对Travis进行了一些优化 Linkify() 上面的代码。我还修复了一个错误,即子域类型格式的电子邮件地址不匹配(即。example@domain.co.uk)。

    此外,我将实现更改为原型 String 类,以便项目可以这样匹配:

    var text = 'address@example.com';
    text.linkify();
    
    'http://stackoverflow.com/'.linkify();
    

    不管怎样,这是剧本:

    if(!String.linkify) {
        String.prototype.linkify = function() {
    
            // http://, https://, ftp://
            var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
    
            // www. sans http:// or https://
            var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
    
            // Email addresses
            var emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim;
    
            return this
                .replace(urlPattern, '<a href="$&">$&</a>')
                .replace(pseudoUrlPattern, '$1<a href="http://$2">$2</a>')
                .replace(emailAddressPattern, '<a href="mailto:$&">$&</a>');
        };
    }