php preg соответствует всем, всем `p`

<?php
$str= <<<ETO
<p>one
two</p>
<p>three</p>
ETO;
preg_match_all('/<p>(.*?)<\/p>/',$str,$r);
print_r($r);
?>

Я изучаю preg_match_all. Я хочу получить все p из одной статьи. но мой код получает только второй p. как изменить так, чтобы я мог получить первый p тоже. Спасибо.


person cj333    schedule 21.03.2011    source источник
comment
Ты неправильно учишься.   -  person BoltClock    schedule 21.03.2011
comment
@BoltClock, не могли бы вы научить меня большему? Спасибо.   -  person cj333    schedule 21.03.2011
comment
Просто регулярное выражение часто является неправильным инструментом для анализа HTML.   -  person BoltClock    schedule 21.03.2011
comment
изучите синтаксический анализатор HTML: stackoverflow.com/questions/ 3577641/best-methods-to-parse-html   -  person Unicron    schedule 21.03.2011


Ответы (2)


Вам не хватает флага /ims в конце регулярного выражения. В противном случае . не будет соответствовать разрывам строк (как в первом абзаце). На самом деле /s было бы достаточно, но для простоты я всегда использую все три.

Кроме того, preg_match работает во многих простых случаях. Но если вы пытаетесь извлечь какие-либо более сложные извлечения, рассмотрите возможность чередования с phpQuery или QueryPath, которые позволяют:

foreach (qp($html)->find("p") as $p)  { print $p->text(); }
person mario    schedule 21.03.2011

(.*?) не соответствует символам новой строки. Попробуйте модификатор /s:

<?php
$str= <<<ETO
<p>one 
two</p>
<p>three</p>
ETO;
preg_match_all('/<p>(.*?)<\/p>/s',$str,$r);
print_r($r);
?>
person Canuteson    schedule 21.03.2011