Есть ли способ для регулярного выражения обнаружить URL-адрес, который не является частью изображения?

#javascript #regex

Вопрос:

У меня есть небольшой чат, который позволяет пользователям форматировать свои сообщения с помощью базового HTML. Ссылки автоматически форматируются в кликабельные ссылки с помощью этой функции:

 function convertToLink(value) {
  var exp = /(b(https?|ftp|file)://[-A-Z0-9 amp;@#/%?=~_|!:,.;]*[-A-Z0-9 amp;@#/%=~_|])/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 атрибуте (это то, что возвращается функцией, когда value есть 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">
 

Я пытался использовать .*".* , чтобы не форматировать ссылку, когда она является частью атрибута, но, похоже, это не работает.

Есть какие-нибудь идеи о том, что мне следует делать?

Комментарии:

1. @JeffC Это всего лишь примеры ссылок.

Ответ №1:

Это хрупкое решение, так как поиск URL-адресов в атрибутах html может привести к ошибкам. Но если 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);