Parse html с регулярным выражением

Я хочу найти все блоки

в этом примере:
<h3>sdf</h3>
sdfsdf
<h3>sdf</h3>
32
<h2>fs</h2>
<h3>23sd</h3>
234
<h2>h1</h2>

(От h3 до другого h3 или h2) Это регулярное выражение находит только первый блок h3

~\<h3[^>]*\>[^>]+\<\/h3\>.+(?:\</h3[^>
<p> Я использую функцию php <span>preg_match_all</span> (Цитата из docs: после того, как найдено первое совпадение, последующие поиски продолжаются с конца последнего совпадения.)</p> <p> Что мне нужно изменить в моем регулярном выражении?</p> <p> п.с.</p> <pre class="prettyprint linenums"><h3>1</h3> 1content <h3>2</h3> 2content <h2>h2</h2> <h3>3</h3> 3content <h2>h1</h2> </pre> <p> этот контент должен быть проанализирован как:</p> <pre class="prettyprint linenums">[0] => <h3>1</h3>1content [1] => <h3>2</h3>2content [2] => <h3>2</h3>3content </pre>

3 ответа

с DOMDocument:

$dom = new DOMDocument();
@$dom->loadHTML($html);

$nodes = $dom->getElementsByTagName('body')->item(0)->childNodes;

$flag = false;
$results = array();

foreach ($nodes as $node) {
 if ( $node->nodeType == XML_ELEMENT_NODE &&
 preg_match('~^h(?:[12]|(3))$~i', $node->nodeName, $m) ):
 if ($flag)
 $results[] = $tmp;
 if (isset($m[1])) {
 $tmp = $dom->saveXML($node);
 $flag = true;
 } else
 $flag = false;

 elseif ($flag):
 $tmp .= $dom->saveXML($node);

 endif;
}

echo htmlspecialchars(print_r($results, true));

с регулярным выражением:

preg_match_all('~


Вы не должны использовать Regex для анализа HTML, если есть какая-либо вложенность.

Regex

(<(h\d)>.*?<\/\2>)[\r\n]([^\r\n<]+)

замена

\1\3
or
$1$3

http://regex101.com/r/uQ3uC2


preg_match_all('/<h3><code>(.*?)&lt;\/h3&gt;/is', $stringHTML, $matches);</code> </h3>

licensed under cc by-sa 3.0 with attribution.