Как сопоставить регулярное выражение, где порядок шаблона не известен - PullRequest
0 голосов
/ 08 января 2019

У меня есть HTML-файл с div, имеющим имя класса. Мне нужно найти div с точным набором заданных классов. Но проблема в том, что я не знаю порядок, в котором классы пишутся внутри div . Например:

Данный список классов : 1, 2, 3

HTML (упрощенно)

<div id="test" class="1 2 3"></div> #A match! since it contains classes 1 2 3
<div id="test" class="3 2 1"></div> #A match! since it contains classes 1 2 3
<div id="test" class="2 1 3"></div> #A match! since it contains classes 1 2 3
<div id="test" class="1 2 3 4"></div> #not a match since it contains other classes than 1, 2, 3
<div id="test" class="1 2 3 5 6"></div> #not a match since it contains other classes than 1, 2, 3

Любое предложение приветствуется!

Редактировать: HTML-текст, как в моем примере, не должен быть действительным. Может содержать несколько div с одинаковым идентификатором или незакрытым div.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Регулярное выражение не будет правильным подходом. Вы хотите сопоставить div по их набору классов - то есть, чтобы пересечение классов из данного входного набора соответствовало набору классов для div:

const findDivsWithClasses = classes => {
  const classesSet = new Set(classes.split(' '));
  return [...document.getElementsByTagName('div')].filter(div =>
    div.classList.length === classesSet.size && [...div.classList].every(className => classesSet.has(className)));
}

console.log(findDivsWithClasses('1 2 3'));
<div id="test" class="1 2 3"></div> #A match! since it contains classes 1 2 3
<div id="test" class="3 2 1"></div> #A match! since it contains classes 1 2 3
<div id="test" class="2 1 3"></div> #A match! since it contains classes 1 2 3
<div id="test" class="1 2 3 4"></div> #not a match since it contains other classes than 1, 2, 3
<div id="test" class="1 2 3 5 6"></div> #not a match since it contains other classes than 1, 2, 3
0 голосов
/ 08 января 2019

Обратите внимание, что дубликаты идентификаторов в одном документе являются недействительными HTML. Если у вас есть контроль над источником, лучше вместо этого использовать классы.

Вместо регулярных выражений (которые часто бывают неуклюжими и не элегантными при разборе HTML), рассмотрите возможность использования DOMParser и затем проверьте classList каждого элемента:

const input = `
<div id="test" class="1 2 3">m1</div> #A match! since it contains classes 1 2 3
<div id="test" class="3 2 1">m2</div> #A match! since it contains classes 1 2 3
<div id="test" class="2 1 3">m3</div> #A match! since it contains classes 1 2 3
<div id="test" class="1 2 3 4">m4</div> #not a match since it contains other classes than 1, 2, 3
<div id="test" class="1 2 3 5 6">m5</div> #not a match since it contains other classes than 1, 2, 3
`;
const doc = new DOMParser().parseFromString(input, 'text/html');
const matchingDivs = Array.prototype.filter.call(
  doc.querySelectorAll('div'),
  ({ classList }) => (
    classList.contains('1') &&
    classList.contains('2') &&
    classList.contains('3') &&
    classList.length === 3
  )
);
console.log(matchingDivs);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...