LINUX.ORG.RU

Regex - как получить содержимое тега?


0

1

У меня есть HTML-документ, внутри которого есть таблица

Мне нужно выделить содержимое таблицы при помощи regex
<table>некий контент</table>

причем сам этот некий контент тоже содержит теги <tr><td>что-то</td></tr>

Как выглядит соответствующий Regex ?


Если бы теги не были вложенными, можно было бы написать что-то вроде
<table>([^<]*)</table>
где внутри выбираются все символы, кроме открывающей угловой скобки.
Но конкретно для table это не пройдет...

А почему бы не выделить сначала таблицу со всеми внутренностями, а потом уже вырезать из неё теги?

GotF ★★★★★
()
Ответ на: комментарий от GotF

почему бы не выделить сначала таблицу со всеми внутренностями


есть страница - http://www.cbr.ru/credit/CO_SitesFull.asp
(собираюсь стать медвежатником)

Там есть одна большая таблица, состоящая из строчек.
В каждой строчке есть вложенная таблица с url-ами сайтов.

Я хочу написать regexp, который выделяет содержимое каждой строки основной таблицы.

StrongDollar
() автор топика

И ещё вопрос. Почему бы не воспользоваться XPath, если есть такая возможность

wxw ★★★★★
()
Ответ на: комментарий от wxw

Почему бы не воспользоваться XPath, если есть такая возможность


возможность есть, однако произвольный html документ в общем случае не является валидным xml (т.е. он должен, но по факту может и не являться)

Функция PHP strip_tags.


а если не PHP ?

StrongDollar
() автор топика

<table>(?<content>(([^<])|([<][^/])|([<][/][^t])|([<][/][t][^a]))*)</table>


На английском форуме на вопрос дают ответ
На еврейском - задают встречный вопрос
и только на русском - объясняют, почему ты дурак...

StrongDollar
() автор топика
Ответ на: комментарий от xcreatepixmap

Решение на Microsoft Visual Studio и .Net сойдёт ?


да я уже справился (dev-lang/mono-2.6.7):

<tr>\r\n
<td[\s]class=«prn»>(?<num>[0-9]*)</td>\r\n
<td[\s]class=«prn»>(?<lic>[0-9]*)</td>\r\n
<td[\s]class=«nm»><a[\s]href="(?<ref>[^«]*)»[\s]target=«_blank»>(?<name>[^<]*)«</a></td>\r\n
<td[\s]class=„sn“>\r\n
<table[\s]class=„ot“>(?<content>(([^<])|([<][^/])|([<][/][^t])|([<][/][t][^a]))*)</table>\r\n
</td></tr>

new Regex (bankRegex, RegexOptions.Multiline | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace);

StrongDollar
() автор топика
Ответ на: комментарий от StrongDollar

>а если не PHP ?

Тогда - жаль. Вырезку тэгов (если без тонкостей) можно сделать тупо в духе s/<[^>]+>//; а вот DOMDocument, который позволяет красиво парсить невалидный HTML я не знаю, чем заменить в других языках ;)

KRoN73 ★★★★★
()
Ответ на: комментарий от StrongDollar

>да я уже справился

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

<td[\s]class=«prn»>

Что будет, когда они поменяют class=«prn» на class=«prn2»? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>парсить невалидный HTML

вроде никто не мешает нормализовать до xml и наложить xslt. И поддерживать это, как ты заметил, будет гораздо проще

wxw ★★★★★
()
Ответ на: комментарий от wxw

вроде никто не мешает нормализовать до xml

Задача может быть в общем случае нерешаема.

<p>...<p>...</p>

Как этот вариант в XML преобразовать? А такой:

<i>...<b>...</i>...</b>
?

:)

При чём второй, хоть, можно в принципе выправить (у меня даже функция соответствующая есть, не помню уже где используется), то первый просто не имеет однозначного решения :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> Регулярно придётся лазить и править свой код

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

StrongDollar
() автор топика
Ответ на: комментарий от KRoN73

> <p>...<p>...</p>

<i>...<b>...</i>...</b>

Как этот вариант в XML преобразовать?



<body>
<p>...</p>
<p>...</p>
</body>

<i>...<b>...</b></i><b>...</b>

а из <i><b>...</i></b>
<i><b>...</b></i>

у меня даже функция соответствующая есть


называется html tidy :)

первый просто не имеет однозначного решения


http://www.w3.org/TR/html401/struct/text.html#h-9.3.1
параграф не может содержать другой параграф

wxw ★★★★★
()
Ответ на: комментарий от wxw

>параграф не может содержать другой параграф

Мы тут, как бы, про ошибки.

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

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Тогда - жаль. Вырезку тэгов (если без тонкостей) можно сделать тупо в духе s/<[^>]+>//; а вот DOMDocument, который позволяет красиво парсить невалидный HTML я не знаю, чем заменить в других языках ;)

тю!

sub HTML_CleanTags{
        my($file)=shift;
        $file=~s/ / /gs;
        $file=~s/\s*<!--.+?-->\s*/<!---->/gs;
        $file=~s/\s*<!.+?>\s*//gs;
        $file=~s/<(script|style).*?<\/\1>//gs;
        $file=~s/\s*<(\/?[!\w]+)((\\["']|(["'])(\\\4|.)*?\4|[^"'>])*?)>\s*/"<".lc($1).lc(HTML_CleanParams($2)).">"/eigs; #"
        return($file);
}

CleanParams - решает что делать с параметрами

simple_best_world_web_master
()
Ответ на: комментарий от KRoN73

> Что будет, когда они поменяют class=«prn» на class=«prn2»? :)

<td[^>]+> - всегда так пишу, также поступает и мой генератор парсилок

simple_best_world_web_master
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.