Помогите с регулярным выражением на javascript
Нужно написать регулярное выражение, которое бы находило слово: «Элемент» (слово может вообще любым быть, суть как раз в его поиске) среди следующего набора тэгов (Сверху и снизу еще и другой html код поэтому поставил троеточие):
...
<a href="main/url.html" class="word_state" data-pjax="">Элемент</a><span> - </span>
...
Еще есть такой момент, что в документе много ссылок , но нужны те у которых в адресе href есть “main”
Мои наработки: (?<="/main/.......(не знаю как поставить n колличество символов)>)(.*)(?=</a><span>) Есть еще проблема, что если есть еще ссылка с окончанием как у этой, то захватывает программа последнюю, а нужно эту
Ответы (1 шт):
/<a[^>]*?\shref="[^"]*main.*?".*?>(.*?)<\/a>/ (Ой!)
>>> https://regex101.com/ может помочь с разбором регулярок.
[^>] — всё что угодно, кроме символа >
*? — ноль или много раз, до тех пор, пока не дойдет до
\shref=" href с обязательным \s пробелом перед ним, в котором встречается main
[^"] гарантирует, что main найдется менно внутри href, пока кавычка не закрыта.
let test = `
+ <a href="main/url.html" class="word_state" data-pjax="">111</a><span></span>
+ <br><a href="/main/url.html">222</a><span></span>
- <br><a href="#" data-href="main">333</a><span></span>
- <br><a href="#">подвох href="main"</a><span></span>
- <br><a href="main/url.html" data-подвох="<a>Маловероятный подвох</a>">444</a>
`;
console.log( getLinkContents(test) );
function getLinkContents(str) {
let reg = /<a[^>]*?\shref="[^"]*main.*?".*?>(.*?)<\/a>/;
let g_reg = new RegExp(reg, "g");
return ( str.match(g_reg) || [] ).map(a => a.match(reg)[1]);
// Сначала находит все совпадения (флажок `g`)
// Потом через map достает только нужный кусок: всё, что попалось внутри скобок (.*?)
// Особенность логического оператора || 'ИЛИ':
// Если match вернет null (в логическом контексте - false),
// возьмется второй [] пустой массив, он и вернется: map с ним ничего не сделает.
}
Но при условии, что HTML-строка прилетает из доверенного источника, или вы предварительно поудаляли всякие <img onerror="Бесконечный цикл">, надежнее будет использовать готовые методы для чтения:
let test = `
+ <a href="main/url.html" class="word_state" data-pjax="">111</a><span></span>
+ <br><a href="/main/url.html">222</a><span></span>
- <br><a href="#" data-href="main">333</a><span></span>
- <br><a href="#">подвох href="main"</a><span></span>
+ <br><a href="main/url.html" data-подвох="<a>Маловероятный подвох</a>">444</a>
`;
console.log( getLinkContents(test) );
function getLinkContents(str) {
let div = document.createElement("div");
div.innerHTML = str;
return [...div.querySelectorAll('a[href*="main"]')].map(a => a.textContent);
}
Где a[href*="main"] - комбинация CSS-селекторов
Но querySelectorAll возвращает коллекцию элементов. У него нет метода map().
А это ... — "Spread" оператор: Добавляет все элементы в настоящий массив, у которого есть встроенный .map()