首页 > 解决方案 > 正则表达式有没有办法检测不属于图像的 URL?

问题描述

我有一个小型聊天室,允许用户使用基本的 HTML 格式化他们的消息。使用此功能,链接会自动格式化为可点击的链接:

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

但是,如果有人发布图像,则图像无法正确显示,因为 URL 被格式化为src属性内的可点击链接(这是函数 when valueis返回的内容https://www.example.com/example.png):

<img src="<a target="_blank" href="https://www.example.com/example.png">https://www.example.com/example.png"</a>">

我想要它做的是返回:

<!--Input-->
https://www.google.com <img src="https://www.example.com/example.png">

<!--Output-->
<a target="_blank" href="https://www.google.com">https://www.google.com</a> <img src="https://www.example.com/example.png">

当它是属性的一部分时,我尝试使用.*\".*不格式化链接,但它似乎不起作用。

关于我应该做什么的任何想法?

标签: javascriptregex

解决方案


这是一个脆弱的解决方案,因为在 html 属性中查找 url 很容易出错。但是如果 url 总是在双引号之间,你可以匹配它来避免它。然后使用替代|并捕获组中的 url,并在替换中使用该组。

如果需要,您可以使模式更具体。另一种选择可能是使用 dom 解析器,并选择此 url 可能出现的元素。

如果您还想考虑单引号,则可以使用另一种替代方法。

"(?:https?|ftp|file):\/\/[^\s"]+"|((?:https?|ftp|file):\/\/[^\s]+)

正则表达式演示

const regex = /"(?:https?|ftp|file):\/\/[^\s"]+"|((?:https?|ftp|file):\/\/[^\s]+)/g;
const str = `https://www.google.com <img src="https://www.example.com/example.png">`;
const res = str.replaceAll(regex, (m, g1) => g1 ? `<a target="_blank" href="${g1}">${g1}</a>` : m);
console.log(res);


推荐阅读