разрыв регулярного выражения на новой строке - PullRequest
1 голос
/ 26 мая 2010

Я пытаюсь использовать регулярное выражение, как показано ниже:

preg_match_all('|<table.*</table>|',$html,$matches, PREG_SET_ORDER);

Но это не работает, и я думаю, что проблема в новой строке внутри строки $html.
Может кто-нибудь сказать мне обойти?


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

Ответы [ 6 ]

4 голосов
/ 26 мая 2010

Точка не соответствует символу новой строки, если не используется модификатор образца s .

preg_match_all('|<table.*?</table>|s',$html,$matches, PREG_SET_ORDER);

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

3 голосов
/ 26 мая 2010

Прежде чем принять решение о том, что делать дальше, я сначала прочту это: http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html

В общем случае разбирать HTMl с RegEx не очень хорошая идея.

Я рекомендую использовать DOM

Вы можете проверить PHP Simple HTML DOM Parser как альтернативу.

Основные характеристики:

  • Анализатор HTML DOM, написанный на PHP5 +, позволяет очень просто манипулировать HTML!
  • Требуется PHP 5 +.
  • Поддерживает недопустимый HTML.
  • Поиск тегов на HTML-странице с селекторами, как у jQuery.
  • Извлечение содержимого из HTML в одну строку.
1 голос
/ 26 мая 2010

Вы пробовали многострочный модификатор m?

preg_match_all('|<table.*</table>|m',$html,$matches, PREG_SET_ORDER);
1 голос
/ 26 мая 2010
preg_match_all('|<table.*?</table>|ms',$html,$matches, PREG_SET_ORDER);
0 голосов
/ 24 июня 2010

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

Лучше: вы можете прочитать $html в объект SimpleXML и проанализировать его с помощью SimpleXML Xpath . (Мощный и гораздо более простой в использовании, чем расширение DOM, ИМХО.)

Как это:

$html = "<html><body><table id=\"mytbl\"><tr><td>ABC</td></tr><tr><td>DEF</td></tr></table></body></html>";

$xml = simplexml_load_string($html);

if($xml)
foreach($xml->xpath("/html/body/*") as $item) {
    echo $item["id"] . "<br>"; // mytbl
    foreach($item->tr as $tr) {
        echo $tr->td . "<br>"; // 1:ABC, 2:DEF
    }
}
0 голосов
/ 27 мая 2010

Используйте флаг / s, чтобы иметь '.' также применяются к символам новой строки или просто проверяют наличие символов новой строки - обычно '[\ n \ r]'. Я еще не читал это сам, но действительно проверяю больше информации о библиотеке PCRE в http://www.pcre.org/pcre.txt

Осторожно, как вы формируете свой шаблон - длинные входные строки с символами новой строки, смешанными с неправильно понятыми шаблонами, могут привести к необъяснимым ошибкам сценария и сбросу соединения.

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

$start = stripos($input, "<table>");
$end = stripos($input, "</table>", $start);
$my_table = substr($input, $start, $end);
...