иерархическое регулярное выражение
Возможно ли / практически ли построить единственное регулярное выражение, которое соответствует иерархическим данным?
Например:
<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 ответа:
Решение состоит в том, чтобы не использовать регулярные выражения. Они недостаточно сильны для такого рода вещей.
Вам нужен парсер - поскольку похоже, что вы пытаетесь соответствовать 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.
Вы должны были бы разработать проверку ошибок самостоятельно, но базовый случай (когда вы возвращаетесь на предыдущий уровень) - это только когда здесь больше нечего искать.
Может, это поможет, а может, и нет. Удачи тебе.