иерархическое регулярное выражение


Возможно ли / практически ли построить единственное регулярное выражение, которое соответствует иерархическим данным?

Например:

<h1>Action</h1>
  <h2>Title1</h2><div>data1</div>
  <h2>Title2</h2><div>data2</div>
<h1>Adventure</h1>
  <h2>Title3</h2><div>data3</div>

Я хотел бы закончить со спичками.

"Action", "Title1", "data1"
"Action", "Title2", "data2"
"Adventure", "Title3", "data3"

Как я вижу, это потребует знания того, что здесь действует иерархическая структура, и если я закодирую шаблон для захвата H1, он будет соответствовать только первой записи этой иерархии. Если я не кодирую H1, то я не могу его захватить. Мне было интересно, есть ли какие-то специальные трюки, которые я использую, чтобы решить это.

Это проект .NET.

3 3

3 ответа:

Решение состоит в том, чтобы не использовать регулярные выражения. Они недостаточно сильны для такого рода вещей.

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

Обычно считается плохой практикой пытаться анализировать HTML/XML с помощью регулярных выражений именно потому, что они иерархичны. Для этого можно использовать рекурсивную функцию, но лучшим решением в этом случае является использование реального синтаксического анализатора XML. Я не мог бы дать вам лучшего совета, не зная платформы, которую вы используете.

EDIT: Regex также очень медленный, что является еще одной причиной, по которой он плохо подходит для обработки HTML; однако я не знаю, что процессор XML/DOM, вероятно, будет быстрее, так как он скорее всего, потребуется гораздо больше памяти.

Если вам просто нужны данные из простого документа, как вы продемонстрировали, и/или если вы хотите построить решение самостоятельно, это не так уж сложно сделать. Просто создайте простой, рекурсивный потоковый процессор на основе состояний, который ищет теги и передает содержимое на следующий рекурсивный уровень.

Например:

- In a recursive function, seek out a "<" character.
- Now find a ">" character.
- Preserve everything you find until the next "<" character.
- Find a ">" character.
- Pass whatever you found between those tags into the recursive function.

Вы должны были бы разработать проверку ошибок самостоятельно, но базовый случай (когда вы возвращаетесь на предыдущий уровень) - это только когда здесь больше нечего искать.

Может, это поможет, а может, и нет. Удачи тебе.

Регулярное выражение не работает для этого типа данных. Это не является регулярным, как таковым.

Для этого следует использовать синтаксический анализатор XML.