JavaScript | Регулярное выражение для извлечения HTML-ссылок из строки

JavaScript | Регулярное выражение для извлечения HTML-ссылок из строки

Что мы считаем HTML-ссылкой в строке?

В этой публикации мы рассматриваем HTML-элементы <a></a>, которые имеют парные тэги:

  1. Открывающий — <a>
  2. Закрывающий — </a>

Мы будем считать, что сами теги и последовательность символов внутри них считается, а также между ними считается HTML-ссылкой.

 

Что мы считаем адресом в HTML-ссылке из строки?

Из HTML-элемента <a></a> нас будет интересовать его атрибут href, который после знака равенства должен содержать двойные кавычки.

Последовательность символов между первой двойной кавычкой и второй двойной кавычкой мы будем считать адресом.

 

Нюансы в решении задачи на извлечение HTML-ссылок

HTML — это гибкий язык. Это значит, что строковое оформление HTML-элементов допускает существование множественного числа пробелов. Например:

<a></a>

то же самое что

<a    ></a     >

Также допускаются символы переносов строк:

<a>

</a>

Эти моменты накладывают дополнительные условия в создании регулярного выражения на JavaScript.

Если сформулировать человеческим языком, то нас интересует последовательность символов, которая начинается со знака МЕНЬШЕ (<), где после него встречается первый символ английской буквы «a» и после него встречается первый символ знака БОЛЬШЕ (>). После него встречается снова первый знак МЕНЬШЕ (<), затем первый символ КОСОЙ ЧЕРТЫ (/), потом первая английская буква «a» и в самом конце первый символ знака БОЛЬШЕ (>).

В общем между всеми нашими символами МЕНЬШЕ-БОЛЬШЕ могут встречаться только пробелы, которые не чувствительны к парсингу HTML.

 

Получение всех HTML-ссылок из строки

Тестовый пример:

let str = `<p><span><span><a    >один</a     ></span><a    >два</a     ></span><a    ><b>три</b></a     ></p>`

Мы подстрахуемся под все возможные ситуации, даже если сервер отдаёт совершенно некорректную ссылку с множественными пробелами:

 

Массив с индексами нахождения начала сопоставления:

[...str.matchAll(/<a *?.*?>.*?<\/a *?>/g)]

Только последовательность с HTML-элементом

[...str.matchAll(/<a *?.*?>.*?<\/a *?>/g)]

 

Получение всех значений HREF из HTML-ссылок из строки

Пример:

let str = `<p><span><span><a style="display: none;" href="/rrttyyu"  >один</a     href="/1234"></span><a  href="http://example.com/efim"  >два</a     ></span><a    ><b>три</b></a     ></p>`

 

Решение:

[...str.matchAll(/<a *?.*? *?href *?= *?"(.*?)".*?>.*?<\/a *?>/g)].map(i=>i[1])