RegEx для извлечения части HTML-элементов - PullRequest
0 голосов
/ 21 мая 2019

поэтому я пытаюсь получить события с этого сайта https://www.oldmuseum.org/ используя тестер регулярных выражений. Это работает, но я также получаю события, которые распроданы.

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

summary-title-link">([^>]+(?!SOLD OUT))<

Произведенная продукция:

'An Evening with Sun Kil Moon'
'Amity Dry- Fortified'
'Teeny Tiny Stevies - SOLD OUT'
'Cine Retro '

Я пытаюсь не распродать событие. Я не уверен, как исправить это регулярное выражение.

Ответы [ 3 ]

2 голосов
/ 21 мая 2019

Если только текст SOLD OUT нежелателен, мы могли бы добавить простую правую границу рядом с этим, что-то вроде:

 summary-title-link">(.+?)(?: - SOLD OUT)<

Первая группа захвата $1 - это желаемая ссылка на заголовок, после которой следуетпо желанию - SOLD OUT.

enter image description here

RegEx

Если это выражение не требуется, его можно изменить или изменить в regex101.com .

Схема RegEx

jex.im также помогает визуализировать выражения.

enter image description here

Демо

const regex = /summary-title-link">(.+?)(- SOLD OUT)?</gm;
const str = `<a href="/event/bpo29sept" class="summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
<a href="/event/bpo29sept" class="summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
<a href="/event/bpo29sept" class="summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
<a href="/event/bpo29sept" class="summary-title-link">Brisbane Philharmonic Orchestra - (Some other data)</a>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Если элементы SOLD OUT не являются полностью необходимыми, мы можем просто удалить их, используя выражение, подобное:

summary-title-link">(((?!SOLD OUT)[\s\S])*?)<\/

enter image description here

Демо

JavaScript Test

const regex = /summary-title-link">(((?!SOLD OUT)[\s\S])*?)<\//gm;
const str = `summary-title-link">Brisbane Philharmonic Orchestra - (Some other data)</a>
summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
summary-title-link">Brisbane Philharmonic Orchestra - (Some other data)</a>
summary-title-link">Brisbane Philharmonic Orchestra - SOLD OUT</a>
summary-title-link">Brisbane Philharmonic Orchestra - (Some other data)</a>
summary-title-link">Brisbane Philharmonic Orchestra - (Some other data)</a>`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}
1 голос
/ 21 мая 2019

Просто скажите, что я не хочу, чтобы в моей строке существовало SOLD OUT.

summary-title-link">(((?!SOLD OUT).)+)<

, следуя этому шаблону, мы говорим о любом символе, который не SOLD OUT заканчивается <.

Демо

0 голосов
/ 21 мая 2019

Причина

Проблема здесь в том, что как жадный квантификатор, [^>]+ будет не только соответствовать содержимому, которое мы хотим (например, «Teeny Tiny Stevies»), но также соответствовать флагу «SOLD OUT», который мы используем для идентификации нежелательный элемент.

Таким образом, когда дело доходит до хода (?!SOLD OUT), он встречает конец строки (то есть $), который на самом деле не является «SOLD OUT», то есть соответствует.

В качестве примера возьмите 'Tiny Stevies - SOLD OUT'. Процесс выглядит следующим образом:

  1. [^>]+: сопоставьте как можно больше [^>], поэтому сопоставьте всю строку «Teeny Tiny Stevies - SOLD OUT».
  2. (?!SOLD OUT): сопоставить позицию, за которой не стоит "SOLD OUT", а конец строки, $, действительно совпадает.

Решение

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

Но мы можем решить проблему с помощью двух регулярных выражений: одно для включения, другое для исключения.

  1. >([^>]+)<: это регулярное выражение получает предметы, хотя некоторые из них не нужны.
  2. , если предмет соответствует SOLD OUT$, выбросить его.

Возможно, есть лучшее решение. Надеюсь, это поможет вам.

...