Регулярное выражение, чтобы найти начало конца списка в HTML - PullRequest
2 голосов
/ 07 мая 2009

У меня есть TextBox на веб-странице, которую я использую JavaScript для анализа и изменения формата HTML. 90% из них работают очень хорошо, последнее, что я пытаюсь поддерживать, это копирование и вставка из текстового документа. Я получил это в основном полностью, я просто застрял на поиске списка и оборачивании их в тег UL ..

Итак, используя регулярные выражения, я бы хотел найти список в этом тексте:

<p>paragraph goes here

<li>goes here<br/>
<li>list item 2<br/>
<li>list item 3<br/>

<p>another paragraph

и оберните раздел <li> тегом <ul>. мое регулярное выражение foo не так хорошо, кто-то может помочь?

----- обновление -----

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

Источником моего контента будет пользователь, копирующий и вставляющий текстовый документ (около 99,9%) времени. Я использую регулярное выражение для вставки тегов HTML в простой текст. для списков я нахожу вставленный в скопированный текст MS-символ маркера и заменяю его тегом <LI>. Я просто хочу сделать более удобным использование тегов <LI> с тегом <UL>.

Я посмотрю на возможность правильно завершить свои теги, так что ... если они правильно завершены, каким будет регулярное выражение, чтобы обернуть мои элементы списка тегом <ul>?

спасибо!

Ответы [ 4 ]

7 голосов
/ 07 мая 2009

Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения». Теперь у них две проблемы. - Джейми Завински

  1. Регулярные выражения и HTML особенно плохо подходят.

  2. Это 2009 год, используйте закрывающие теги в своем HTML. (Это само по себе поможет вам, если вы действительно захотите пересмотреть свой html.

  3. Если у вас уже есть эта страница в браузере, используйте DOM! Позвольте браузеру проанализировать HTML-код за вас (при необходимости поместите его в скрытый div) и перейдите к результирующему дереву DOM.

5 голосов
/ 07 мая 2009

Не анализировать HTML с регулярными выражениями . Вместо этого используйте настоящий HTML-парсер .

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

Кроме того, ни один из ваших тегов не закрыт. Вы, вероятно, должны написать это так:

<p>paragraph goes here</p>

<li>goes here</li>
<li>list item 2</li>
<li>list item 3</li>

<p>another paragraph</p>

Мой HTML может быть отключен, но вы должны действительно закрыть все ваши теги.

1 голос
/ 07 мая 2009

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

Давайте предположим, что вы используете Java на данный момент. Если вы знаете, что ваш ввод является допустимым XHTML вместо HTML, вы можете использовать Java API для обработки XML (JAXP), который поставляется с Sun Java JDK. Затем в несколько строк вы можете разобрать свой XHTML в дерево DOM и наклониться вниз, чтобы выбрать узел списка и делать с ним все, что вам нравится. У JAXP есть кривая обучения, но оно того стоит.

Если вы используете Groovy, есть XMLSlurper. В Ruby есть несколько хороших библиотек XML. PHP имеет расширение XMLParser. Питон имеет Красивый суп . Практически любой современный язык имеет хорошие альтернативы на выбор.

Теперь, основываясь на вашем примере, вы не имеете правильно XHTML с XML-символами, но безрассудно выглядящий HTML с незакрытыми тегами и другими неприятностями. Если это так, вам нужно взять библиотеку HTML-анализатора, что-то вроде HTMLParser . Удачи!

0 голосов
/ 07 мая 2009

Предполагая, что все элементы имеют конечные теги, и никто не стал умным, добавив пробелы внутри начальных или конечных тегов, и что некоторые элементы предшествуют элементам списка, все, что вам нужно сделать, это примерно так (в синтаксисе Perl, вероятно, совместимо с PCRE библиотека, минус оператор m//):

m/(?<!li)>[^<]*<li/i

для идентификации первого списка в группе. В разобранном виде (с флагом x, для удобства чтения):

m/
    (?<!li)> # the end of a start or end tag that isn't part of an li element
    [^<]*    # some non-angle-bracket characters -- in-between tag content
    <li      # the beginning of an li element
/xi          # space insensitive, case insensitive (respectively)

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


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

m/(?<=<li).*?<(div|form|p)/i

, где вы перечисляете все не встроенные элементы, что приведет к закрытию li и ul и завершению всего списка. Но другой способ закрытия списка - простота - закрытие контейнера.


Если сами элементы элемента списка правильно сформированы (имеют закрывающие теги), то этого может быть достаточно для размещения закрывающего тега списков:

m{</li>.*?<(?!li)}i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...