Regex - я хочу сопоставить только начальные теги в regex - PullRequest
2 голосов
/ 23 февраля 2009

Я делаю регулярное выражение, в котором я хочу сопоставлять только неправильные теги, такие как: <p> *some text here, some other tags may be here as well but no ending 'p' tag* </p>

 <P>Affectionately Inscribed </P><P>TO </P><P>HENRY BULLAR, </P><P>(of the western circuit)<P>PREFACE</P>

В приведенном выше тексте я хочу получить результат как <P>(of the western circuit)<P>, и больше ничего не должно быть зафиксировано. Я использую это, но это не работает:

<P>[^\(</P>\)]*<P>

Пожалуйста, помогите.

Ответы [ 5 ]

7 голосов
/ 23 февраля 2009

Regex не всегда является хорошим выбором для данных типа xml / html. В частности, большое влияние оказывают атрибуты, чувствительность к регистру, комментарии и т. Д.

Для xhtml я бы использовал XmlDocument / XDocument и запрос xpath.

Для "не-x" html я бы посмотрел на HTML Agility Pack и то же самое.

1 голос
/ 23 февраля 2009

Я знаю, что это вряд ли (или даже html-legal?) Произойдет в этом случае, но общее закрытое решение xml-тега будет довольно трудным, так как вам нужно учитывать, что произойдет с вложенными тегами, такими как

<p>OUTER BEFORE<p>INNER</p>OUTER AFTER</p>

Я почти уверен, что приведенные до сих пор регулярные выражения будут соответствовать второму <p>, хотя на самом деле оно не является незамеченным <p>.

1 голос
/ 23 февраля 2009

Первая группа матчей:

(?:<p>(?:(?!<\/?p>).?)+)(<p>)

соответствует второму <p> в:

<P>(of the western circuit)<P>PREFACE</P>

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

0 голосов
/ 23 февраля 2009

Все предлагаемые решения соответствуют второму

, но это не так. Что делать, если есть два последовательных элемента

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

@"<p\b(?>(?:[^<]+|<(?!/?p>))*)(?=<p\b|$)"

Что касается остального, я использовал технику «не начальный или не остальной» вместе с атомарной группой, чтобы привести регулярное выражение к совпадению настолько эффективно, насколько это возможно (и, что более важно, провалиться так же быстро, как возможно, если это будет).

0 голосов
/ 23 февраля 2009

Вместо того, чтобы использовать * для максимального соответствия, используйте *? для минимального.

Должен быть в состоянии начать с

<P>((?!</P>).)*?<P>

При этом используется отрицательное утверждение о том, что конечный тег не совпадает в каждой точке между совпадениями "<P>".

РЕДАКТИРОВАТЬ: Исправлено, чтобы поставить утверждение (благодаря комментатор).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...