Что мы считаем HTML-ссылкой в строке?
В этой публикации мы рассматриваем HTML-элементы <a></a>, которые имеют парные тэги:
- Открывающий — <a>
- Закрывающий — </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])