【问题标题】:How to replace plain URLs with links?如何用链接替换纯 URL?
【发布时间】:2010-09-07 10:49:56
【问题描述】:

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

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

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

    问题中的正则表达式错过了很多的边缘情况。在检测 URL 时,最好使用专门的库来处理国际域名、.museum 等新 TLD、URL 内部和末尾的括号和其他标点符号,以及许多其他极端情况。请参阅 Jeff Atwood 的博文 The Problem With URLs,了解对其他一些问题的解释。

    网址匹配库的最佳总结Dan Dascalescu's Answer
    (截至 2014 年 2 月)


    “使正则表达式替换多个匹配项”(具体问题解答)

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

    /ig;
    

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

    【讨论】:

      【解决方案2】:

      我不得不反其道而行之,只将 html 链接添加到 URL 中,但我修改了您的正则表达式,它的工作原理就像一个魅力,谢谢 :)

      var exp = /.*/ig; source = source.replace(exp,"$1");

      【讨论】:

      • 我看不出你的正则表达式的意义。它匹配一切,用一切代替一切。实际上,您的代码什么都不做。
      • 我想我应该等待评论让人们完成编辑。对不起。
      【解决方案3】:

      谢谢,这很有帮助。我还想要一些能够链接看起来像 URL 的东西的东西——作为基本要求,它会链接像 www.yahoo.com 这样的东西,即使 http:// 协议前缀不存在。所以基本上,如果“www”。存在,它将链接它并假设它是 http://。我还希望电子邮件变成 mailto: 链接。示例:www.yahoo.com 将转换为 www.yahoo.com

      这是我最终得到的代码(结合本页面的代码和我在网上找到的其他东西,以及我自己做的其他东西):

      function Linkify(inputText) {
          //URLs starting with http://, https://, or ftp://
          var replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
          var 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)
          var replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
          var replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>');
      
          //Change email addresses to mailto:: links
          var replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;
          var replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');
      
          return replacedText
      }
      

      在第二次替换中, (^|[^/]) 部分仅在 www.whatever.com 尚未以 // 为前缀的情况下替换它——以避免在第一个 URL 已链接的情况下进行双重链接代替。此外,www.whatever.com 可能位于字符串的开头,这是正则表达式该部分中的第一个“或”条件。

      这可以集成为一个 jQuery 插件,如上面的 Jesse P 所示——但我特别想要一个不作用于现有 DOM 元素的常规函数​​,因为我正在获取我拥有的文本,然后将其添加到DOM,我希望文本在添加之前被“链接”,所以我通过这个函数传递文本。效果很好。

      【讨论】:

      • 第二种模式存在问题,它完全匹配纯“www.domain.com”。当 url 中有某种引荐来源网址时存在问题,例如:&location=http%3A%2F%2Fwww.amazon.com%2FNeil-Young%2Fe%2FB000APYJWA%3Fqid%3D1280679945%26sr%3D8-2-ent&tag=tra0c7 -20&linkCode=ur2&camp=1789&creative=9325 - 在这种情况下,链接会再次自动链接。一个快速的解决方法是在包含“/”的否定列表之后添加字符“f”。所以表达式是:replacePattern2 = /(^|[^\/f])(www\.[\S]+(\b|$))/gim
      • 上面的代码会在很多边缘案例的测试中失败。检测 URL 时,最好依靠专门的库。 Here's why.
      • 我只是在一个字符串上运行它,其中一些网络链接确实已经有一个 href 链接。在这种情况下,它无法弄乱现有的工作链接。
      【解决方案4】:

      上述 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 时,最好依赖专门的库。 Here's why.
      • 谢谢,@DanDascalescu 通常,过度概括总是更好。
      【解决方案5】:

      【讨论】:

      【解决方案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;
      }
      

      【讨论】:

      • 如何编辑此代码以不损害嵌入式对象和 iframe..(youtube 嵌入式对象和 iframe)
      • 代码中存在与此处的电子邮件地址匹配的错误。 [a-zA-Z]{2,6} 应该阅读类似于 (?:[a-zA-Z]{2,6})+ 的内容,以便匹配更复杂的域名,即 email@example.co.uk。
      • 我遇到了一些问题;首先只是 http:// 或 http:// www (没有空格 www 甚至 SO 显然会解析这个错误)将创建一个链接。并与 http://www 链接。领域 。 com(不带空格)将创建一个空链接,然后在 href 字段中创建一个带有锚定结束标记的链接。
      • 没有http://www 的URL 怎么办?这对那些类型的 URL 有效吗?
      • 我尝试编辑原始帖子以修复 mailto 问题,但我必须添加至少 6 个字符才能进行编辑。但是,如果您更改此行:replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim; 与此 replacePattern3 = /(\w+@[a-zA-Z_]+?(\.[a-zA-Z]{2,6})+)/gim; 修复 mailto 问题:)
      【解决方案7】:

      对上面的 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>');
          };
      }
      

      【讨论】:

      • 在我看来是最好的,因为原型函数让事情变得更加简洁:)
      • 它似乎不适用于这样的电子邮件地址:info@some-thing.com some.thing@example.com etc..
      • @MarcoGagliardi 不错。固定。
      • 这不适用于字符串“git clone aaaa@bitbucket.org/ooo/bbb-cc-dd.git”。它将字符串分成块并创建了多个锚点,例如“git clone aaaa@bitbucket.org/ooo/ bbb-cc-dd.git">https://aaaa@bitbucket.org/ooo/bbb-cc-dd.git "
      • 它不适用于电子邮件用户名中的+,例如foo+bar@domain.com。我用电子邮件模式/[\w.+]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim 修复了它(注意第一个括号中的+),但我不知道这是否会破坏其他内容。
      【解决方案8】:

      我将 Roshambo String.linkify() 更改为 emailAddressPattern 以识别 aaa.bbb.@ccc.ddd 地址

      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 *** here I've changed the expression ***
              var emailAddressPattern = /(([a-zA-Z0-9_\-\.]+)@[a-zA-Z_]+?(?:\.[a-zA-Z]{2,6}))+/gim;
      
              return this
                  .replace(urlPattern, '<a target="_blank" href="$&">$&</a>')
                  .replace(pseudoUrlPattern, '$1<a target="_blank" href="http://$2">$2</a>')
                  .replace(emailAddressPattern, '<a target="_blank" href="mailto:$1">$1</a>');
          };
      }
      

      【讨论】:

      • 上面的代码会在很多边缘案例的测试中失败。检测 URL 时,最好依靠专门的库。 Here's why.
      【解决方案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>");
      }
      

      【讨论】:

        【解决方案10】:

        识别 URL 很棘手,因为它们通常被标点符号包围,而且用户经常不使用 URL 的完整形式。存在许多用于用超链接替换 ​​URL 的 JavaScript 函数,但我无法在基于 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. &lt;grin&gt;"
        

        如果第二个参数为真,则会插入rel="nofollow"。第三个参数,如果为真,转义在 HTML 中具有特殊含义的字符。见the README file

        【讨论】:

        • 也适用于 html 源,例如:www.web.com url some text
        • @Paulius:如果您将选项 django_compatible 设置为 false,它将更好地处理该用例。
        • Django 的 urlize 不正确支持 TLD(至少不支持 GitHub 上的 JS 端口)。 handles TLDs properlyBen Alman's JavaScript Linkify 的库。
        • 支持检测具有额外顶级域的 URL,即使 URL 不以“http”或“www”开头。
        【解决方案11】:

        此解决方案与许多其他解决方案一样工作,实际上使用与其中一个相同的正则表达式,但是它不会返回 HTML 字符串,而是返回包含 A 元素和任何适用文本节点的文档片段。

         function make_link(string) {
            var words = string.split(' '),
                ret = document.createDocumentFragment();
            for (var i = 0, l = words.length; i < l; i++) {
                if (words[i].match(/[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi)) {
                    var elm = document.createElement('a');
                    elm.href = words[i];
                    elm.textContent = words[i];
                    if (ret.childNodes.length > 0) {
                        ret.lastChild.textContent += ' ';
                    }
                    ret.appendChild(elm);
                } else {
                    if (ret.lastChild && ret.lastChild.nodeType === 3) {
                        ret.lastChild.textContent += ' ' + words[i];
                    } else {
                        ret.appendChild(document.createTextNode(' ' + words[i]));
                    }
                }
            }
            return ret;
        }
        

        有一些注意事项,即旧版 IE 和 textContent 支持。

        here 是一个演示。

        【讨论】:

        • @DanDascalescu 可能会提供您所说的边缘案例,而不是一揽子投票。
        • 所以有边缘情况。精彩的。这些答案仍然可能对其他人有用,并且对它们一票否决似乎过大了。您评论过且似乎被否决的其他答案确实包含有用的信息(以及您的答案)。不是每个人都会反对上述案例,也不是每个人都想使用图书馆。
        • 没错。那些不了解正则表达式限制的人会很乐意从最受好评的答案中略过第一个正则表达式并使用它。这些是最应该使用图书馆的人。
        • 但是,用非您的首选解决方案正则表达式否决每个答案的理由是什么?
        • 这样一个真正有用的答案就会出现在顶部。人们的注意力很短,paradox of choice 表示他们将不再寻找 N 次之后的答案。
        【解决方案12】:

        经过多个来源的输入后,我现在有了一个运行良好的解决方案。它与编写您自己的替换代码有关。

        Answer.

        Fiddle.

        function replaceURLWithHTMLLinks(text) {
            var re = /(\(.*?)?\b((?:https?|ftp|file):\/\/[-a-z0-9+&@#\/%?=~_()|!:,.;]*[-a-z0-9+&@#\/%=~_()|])/ig;
            return text.replace(re, function(match, lParens, url) {
                var rParens = '';
                lParens = lParens || '';
        
                // Try to strip the same number of right parens from url
                // as there are left parens.  Here, lParenCounter must be
                // a RegExp object.  You cannot use a literal
                //     while (/\(/g.exec(lParens)) { ... }
                // because an object is needed to store the lastIndex state.
                var lParenCounter = /\(/g;
                while (lParenCounter.exec(lParens)) {
                    var m;
                    // We want m[1] to be greedy, unless a period precedes the
                    // right parenthesis.  These tests cannot be simplified as
                    //     /(.*)(\.?\).*)/.exec(url)
                    // because if (.*) is greedy then \.? never gets a chance.
                    if (m = /(.*)(\.\).*)/.exec(url) ||
                            /(.*)(\).*)/.exec(url)) {
                        url = m[1];
                        rParens = m[2] + rParens;
                    }
                }
                return lParens + "<a href='" + url + "'>" + url + "</a>" + rParens;
            });
        }
        

        【讨论】:

        • 上面的代码(以及一般的大多数正则表达式)将无法通过边缘情况的大量测试。检测 URL 时,最好依靠专门的库。 Here's why.
        • 丹,有这样的图书馆吗?尽管在这种情况下,我们仍然会匹配上面的正则表达式,这样当像垃圾一样的东西(即使另一个库证明垃圾是有效的 URL/URI)作为输入时,代码永远不会输出垃圾。
        【解决方案13】:

        注册示例: /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&amp;@#\/%?=~_|!:,.;]*[-A-Z0-9+&amp;@#\/%=~_|]*)/ig

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

        以下是一些经过测试的字符串:

        1. 在 www.google.com 上找到我
        2. www
        3. 找我到 www.http://www.com
        4. 关注我:http://www.nishantwork.wordpress.com
        5. http://www.nishantwork.wordpress.com
        6. 关注我:http://www.nishantwork.wordpress.com
        7. https://stackoverflow.com/users/430803/nishant

        注意:如果您不想将www 作为有效的传递,只需使用下面的 reg ex: /(\b((https?|ftp|file):\/\/|(www))[-A-Z0-9+&amp;@#\/%?=~_|!:,.;]*[-A-Z0-9+&amp;@#\/%=~_|])/ig

        【讨论】:

        • 上面的代码会在很多边缘案例的测试中失败。检测 URL 时,最好依赖专门的库。 Here's why.
        【解决方案14】:

        首先,使用自己的正则表达式来解析 URL 是一个糟糕的想法。根据the RFCs,您必须想象这是一个很常见的问题,有人已经为它编写、调试和tested 一个库。 URI 很复杂 - 查看code for URL parsing in Node.jsURI schemes 上的维基百科页面。

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

        我查看了libraries 中的a ton,尽管有一些缺点,但仍有一些值得使用:

        我很快就取消了这项任务的资格:

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

        【讨论】:

        • 很遗憾URL regexp from Component 没有被评论,对它所做的一些解释会有所帮助。 Autolinker.js 的评论非常好并且有测试。 Vebjorn Ljosa's answer 中链接的 urlize.js 库看起来也很有特色且维护良好,尽管它没有测试。
        • Regex101.com automatically "explains" 正则表达式,但祝你好运 :) 我也很快发现了一个无效 TLD 的失败案例(相同的链接)。
        • 很好奇没有人提到 John Gruber 为维护 URL regex pattern 所做的努力。这不是解决问题的唯一/理想解决方案,但无论如何都值得调查,如果您正在推出自己的解决方案。只是想添加这个作为参考。
        • @DanDascalescu 看看这个markdown-it.github.io/linkify-it。这个库只专注于一项任务——检测文本中的链接模式。但我希望,它做得很好。例如,它具有正确的 unicode 支持,包括星体字符。它支持国际顶级域名。
        • 加 1 用于 Autolinker.js,如果您正在寻找它,则易于实施、快速的解决方案。谢谢
        【解决方案15】:

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

        如上所述,网址可能非常复杂,尤其是在“?”之后,而且并非所有网址都以“www”开头。例如maps.bing.com/something?key=!"£$%^*()&amp;lat=65&amp;lon&amp;lon=20

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

        匹配

        http(s):// (anything but a space)+

        www. (anything but a space)+

        “任何东西”是[^'"&lt;&gt;\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;
        

        【讨论】:

          【解决方案16】:

          具有国际域和星体字符支持的正确 URL 检测并非易事。 linkify-it 库从 many conditions 构建正则表达式,最终大小约为 6 KB :) 。它比目前在接受的答案中引用的所有库更准确。

          请参阅linkify-it demo 以实时检查所有边缘情况并测试您的情况。

          如果需要链接 HTML 源代码,则应先对其进行解析,然后分别迭代每个文本标记。

          【讨论】:

            【解决方案17】:

            用 HTML 链接替换文本中的 URL,忽略 href/pre 标记中的 URL。 https://github.com/JimLiu/auto-link

            【讨论】:

              【解决方案18】:

              我已经编写了另一个 JavaScript 库,它可能对您更好,因为它非常敏感,误报最少,速度快且体积小。我目前正在积极维护它,所以请对它进行测试in the demo page,看看它对你有什么作用。

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

              【讨论】:

              • 很棒的图书馆。非常感谢!
              【解决方案19】:

              我在 google 上搜索了任何更新的内容并遇到了这个:

              $('p').each(function(){
                 $(this).html( $(this).html().replace(/((http|https|ftp):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, '<a href="$1">$1</a> ') );
              });
              

              演示: http://jsfiddle.net/kachibito/hEgvc/1/

              非常适合普通链接。

              【讨论】:

              • 这里的“普通链接”是什么?在此处查看您的演示的分支:jsfiddle.net/hEgvc/27 人们会覆盖未覆盖的内容,并且会以简单的方式完成此操作。根据 RFC3986,URI 并不容易,如果您只想涵盖“普通链接”,我建议至少遵循这个正则表达式:^(([^:/?#]+):)?(//([ ^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
              • 我的意思是 http://example.com/folder/folder/folder/https://example.org/blah 等格式的任何内容 - 只是典型的非疯狂 URL 格式,将匹配 95-99% 的用例。我将它用于内部管理区域,所以我不需要任何花哨的东西来捕捉边缘情况或哈希链接。
              • 谢谢你终于帮了我的忙!我只需要稍微修改一下:/(?:^|[^"'&gt;])((http|https|ftp):\/\/[\w?=&amp;.\/-;#~%-]+(?![\w\s?&amp;.\/;#~%"=-]*&gt;))/gi
              【解决方案20】:

              应注意有关 URI 复杂性的警告,但您的问题的简单答案是:
              要替换每个匹配项,您需要将 /g 标志添加到正则表达式的末尾:
              /(\b(https?|ftp|file):\/\/[-A-Z0-9+&amp;@#\/%?=~_|!:,.;]*[-A-Z0-9+&amp;@#\/%=~_|])/gi

              【讨论】:

                【解决方案21】:

                这是我的解决方案:

                var content = "Visit https://wwww.google.com or watch this video: https://www.youtube.com/watch?v=0T4DQYgsazo and news at http://www.bbc.com";
                content = replaceUrlsWithLinks(content, "http://");
                content = replaceUrlsWithLinks(content, "https://");
                
                function replaceUrlsWithLinks(content, protocol) {
                    var startPos = 0;
                    var s = 0;
                
                    while (s < content.length) {
                        startPos = content.indexOf(protocol, s);
                
                        if (startPos < 0)
                            return content;
                
                        let endPos = content.indexOf(" ", startPos + 1);
                
                        if (endPos < 0)
                            endPos = content.length;
                
                        let url = content.substr(startPos, endPos - startPos);
                
                        if (url.endsWith(".") || url.endsWith("?") || url.endsWith(",")) {
                            url = url.substr(0, url.length - 1);
                            endPos--;
                        }
                
                        if (ROOTNS.utils.stringsHelper.validUrl(url)) {
                            let link = "<a href='" + url + "'>" + url + "</a>";
                            content = content.substr(0, startPos) + link + content.substr(endPos);
                            s = startPos + link.length;
                        } else {
                            s = endPos + 1;
                        }
                    }
                
                    return content;
                }
                
                function validUrl(url) {
                    try {
                        new URL(url);
                        return true;
                    } catch (e) {
                        return false;
                    }
                }
                

                【讨论】:

                  【解决方案22】:

                  试试下面的功能:

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

                  alert(anchorify("Hola amigo! https://www.sharda.ac.in/academics/"));

                  【讨论】:

                  • https:// https://www. http:// http://www. www. 配合使用效果很好
                  【解决方案23】:

                  试试下面的解决方案

                  function replaceLinkClickableLink(url = '') {
                  let pattern = new RegExp('^(https?:\\/\\/)?'+
                          '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+
                          '((\\d{1,3}\\.){3}\\d{1,3}))'+
                          '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+
                          '(\\?[;&a-z\\d%_.~+=-]*)?'+
                          '(\\#[-a-z\\d_]*)?$','i');
                  
                  let isUrl = pattern.test(url);
                  if (isUrl) {
                      return `<a href="${url}" target="_blank">${url}</a>`;
                  }
                  return url;
                  }
                  

                  【讨论】:

                    【解决方案24】:
                    /**
                     * Convert URLs in a string to anchor buttons
                     * @param {!string} string
                     * @returns {!string}
                     */
                    
                    function URLify(string){
                      var urls = string.match(/(((ftp|https?):\/\/)[\-\w@:%_\+.~#?,&\/\/=]+)/g);
                      if (urls) {
                        urls.forEach(function (url) {
                          string = string.replace(url, '<a target="_blank" href="' + url + '">' + url + "</a>");
                        });
                      }
                      return string.replace("(", "<br/>(");
                    }
                    

                    simple example

                    【讨论】:

                      【解决方案25】:

                      为我工作:

                      var urlRegex =/(\b((https?|ftp|file):\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?)/ig;
                      
                      return text.replace(urlRegex, function(url) {
                          var newUrl = url.indexOf("http") === -1 ? "http://" + url : url;
                          return '<a href="' + newUrl + '">' + url + '</a>';
                      });
                      

                      【讨论】:

                        猜你喜欢
                        • 2013-11-02
                        • 2014-02-21
                        • 2020-07-21
                        • 2015-02-14
                        • 2012-01-14
                        • 2016-01-17
                        相关资源
                        最近更新 更多