用正则表达式解析html

时间:2014-04-04 00:45:01

标签: php regex html-parsing preg-match preg-match-all

我想找到所有< h3>这个例子中的块:

<h3>sdf</h3>
sdfsdf
<h3>sdf</h3>
32
<h2>fs</h2>
<h3>23sd</h3>
234
<h1>h1</h1>

(从 h3 到其他 h3 h2 )此正则表达式仅查找第一个 h3

~\<h3[^>]*\>[^>]+\<\/h3\>.+(?:\<h3|\<h2|\<h1)~is

我使用php函数 preg_match_all (引自文档:在找到第一个匹配项后,后续搜索将从最后一场比赛结束时继续。

我的regexp需要修改什么?

PS

<h3>1</h3>
1content
<h3>2</h3>
2content
<h2>h2</h2>
<h3>3</h3>
3content
<h1>h1</h1>

此内容必须解析为:

[0] => <h3>1</h3>1content
[1] => <h3>2</h3>2content
[2] => <h3>2</h3>3content

3 个答案:

答案 0 :(得分:1)

如果涉及任何嵌套,您不应该使用正则表达式解析HTML。

正则表达式

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

替换

\1\3
or
$1$3

http://regex101.com/r/uQ3uC2

答案 1 :(得分:1)

使用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('~<h3.*?(?=<h[123])~si', $html, $matches);

echo htmlspecialchars(print_r($matches[0], true));

答案 2 :(得分:0)

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