иерархическое регулярное выражение - PullRequest
3 голосов
/ 11 февраля 2010

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

Например:

<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 ]

5 голосов
/ 11 февраля 2010

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

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

2 голосов
/ 11 февраля 2010

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

РЕДАКТИРОВАТЬ: 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.

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

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

0 голосов
/ 11 февраля 2010

Regex не работает для этого типа данных. Это не регулярно, как таковой.

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

...