javascript - 将 URL 或完全限定域名替换为链接

标签 javascript regex

我不擅长常规经验。 我想将链接更改为文本中的超链接

例如

Hello http://stackoverflow.com
Hello www.stackoverflow.com

我想要 stackoverflow 链接

Hello <a href='http://stackoverflow.com'>http://stackoverflow.com</a>
Hello <a href='http://www.stackoverflow.com'>www.stackoverflow.com</a>

我用过这个

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

但这仅适用于 http://

提前致谢

最佳答案

正如其他人所说,首先您需要定义什么是“链接”。 (请注意,在这种情况下,“link”只是“hyperlink”的缩写,因此您的这句话没有意义。)考虑到您的两个示例,您想要匹配 Uniform Resource Identifiers (URIs)Fully Qualified Domain Names (FQDNs)相反。

为此,您应该采用 RFC 3986, Appendix B 中可以找到的正则表达式。 –

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?

– 并将其更改为在字边界处匹配,仅接受 FQDN 和 // 之后的可选端口号,并在空格 (\s) 处停止:

      ,----scheme----.   ,-Fully Qualified Domain Name-.,-port.,--path--.,---query----.,fragment
      |              |   |                             ||     ||        ||            ||       |
(^|\s)(([^:/?#\s]+):)?(//([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?

然后您可以将方案部分设为可选 -

                          |
                          v
(^|\s)((([^:/?#\s]+):)?//)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?

– 并将其写为正则表达式文字(表达式中的斜杠需要转义,因为它们用作分隔符):

/(^|\s)((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?/

(您可能也想匹配 IDNs ;JSX:regexp.js 及其对 Unicode 字符属性的支持可以帮助您,请参阅 How to remove all characters from a string 。并且您可能希望在 FQDN 子表达式前面添加一个子表达式URI 中可选且已弃用的用户名传输,(\w+@)?,用于代理访问。)

然后您可以替换与相应的 a 元素匹配的所有字符串(global 修饰符):

var rx = /(^|\s)(((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?)/g;

str = str.replace(rx,
  function (match, optionalWhitespace, uri, scheme, p4, protocol, fqdn, p7, port,
            path, query, queryVal, fragment, fragId) {
    return (optionalWhitespace ? optionalWhitespace : '')
      + '<a href="' + (protocol ? uri : 'http://' + uri)
      + '" target="_blank">' + uri + '<\/a>';
  });

此处您必须假设,当您仅看到 FQDN 前缀时,它是不安全网站的域名,并在前面添加 http://。否则,href 属性中的 URI 引用将引用您的网站中可能存在的路径,该路径以域名作为名称 (http://your-site.example/other-site.example.com),这可能不是您想要的。

这个表达式有可能(但不太可能)与您的情况匹配太多;使用尽可能多的可用输入进行测试,并根据需要进行调整。如果向后兼容性不是问题,请使用 non-capturing parentheses ((?:…)) 提高效率并减少命名参数;请参阅ECMAScript Support Matrix了解详情。

捕获 FQDN 部分 - ([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+ 周围的括号 - 是可选的;您可能想使用它为 a 元素提供一个 class 属性值,以特殊方式对其进行格式化,例如在前面添加一个合适的图标,例如指向 Stack 的链接Overflow、维基百科、Twitter 或 Facebook。

您可能还需要重新考虑使用 target 属性 ( for Strict (X)HTML, you MUST remove it )。用户可能不会接受无法控制链接目标的打开位置。以标题、图标、光标等形式提供提示。

关于javascript - 将 URL 或完全限定域名替换为链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10813379/

相关文章:

javascript - Vue 2 - 在悬停和单击时删除类(带有多个元素)

r - 如何使用 grep 提取日期?我需要为每一个匹配 ", "、 "/"、 ". "、 "- "

javascript - 使用 Google Apps 脚本在 Gmail 中内嵌图像

python - re.sub(...) 替换最左边的事件?

Java模式匹配进入无限循环

javascript - JS/Jquery,匹配未找到 PNG = 匹配 ('/gif|jpg|jpeg|png/' )

javascript - 使用 then() 进行 Arangodbjs 查询在 IE11 上不起作用

javascript - Node.js 返回的不是一个函数

使用 reduce 将 Javascript 对象转换为查询字符串

javascript - 如何在绘制第二个多边形后删除多边形