2

假设我有以下代码:

<div class="content">
    <h3>Test</h3>
    <img src="#" alt="" />
    <p>Lorem ipsum</p>
    <p>dolor sit</p>
    <p><!-- pagebreak --></p>
    <p>amet</p>
</div>

我想修剪我的代码并在分页后删除所有内容,但保留 html 逻辑(</div>):

<div class="content">
    <h3>Test</h3>
    <img src="#" alt="" />
    <p>Lorem ipsum</p>
    <p>dolor sit</p>
</div>

工具:Zend,常规 PHP。

有任何想法吗?

4

2 回答 2

3

您可以使用 xpath 来访问这些节点,如下所示:

$doc = new DOMDocument;
$doc->loadHTML($html); // your content with a between '<html></html>' pair
$xpath = new DOMXpath($doc);
$elements = $xpath->query('//p[contains(comment(), "pagebreak")]/following-sibling::*|//p[contains(comment(), "pagebreak")]');
foreach ($elements as $elem) {
    $elem->parentNode->removeChild($elem);
}   

print $doc->saveHTML();

xpath的一个小故障:

  • //p每个 P 元素。
  • //p[]过滤 P 的列表,就像它是一个数组一样。
  • //p[contains(comment(), "pagebreak")]如果他们的 comment() 值包含“pagebreak”字符串,则过滤。
  • //p[contains(comment(), "pagebreak")]/following-sibling::*已经选择了 P 的每个后续兄弟。
  • 另一部分只是一个|没有该部分的具有相同模式的并集 ( ) following-sibling::*

编辑:

一个可能不那么毛茸茸的 xpath 将是:

//p[contains(comment(), "pagebreak")]/preceding-sibling::*[1]/following-sibling::*

这通过在同级列表中后退一个(此时针对<p>带有注释的那个之前的那个)来解决问题,并拥有该节点的following-siblings::*

于 2012-08-03T15:06:23.997 回答
0

我做到了 !我把它当作个人挑战,我终于用正则表达式做到了!
这段代码可能没有优化,那么请不要犹豫告诉我如何改进它(但使用正则表达式,而不是 DOM),但它仍然有效!:)

$str = '<div>
    <h3>Test</h3>
    <img/>
    <p>Lorem ipsum</p>
    <p>dolor sit</p>
    <p><-- pagebreak --></p>
    <p>amet</p>
    <blockquote>
        <p>
            lol
        <p>
    </blockquote>
</div>';


$pagebreak_str = '-- pagebreak --';
$weird_replacement = '§~@';

$parsed = array();
$is_below_break = false;

while (preg_match ("#<([^/]+)>#isU",$str)) {
    if ($is_below_break) {
        $str = preg_replace ("#<" .$pagebreak_str. ">#isU", "", $str);
        $str = preg_replace ("#<[^/>]+>(.+)</[^/>]+>#isU", "", $str);
        $str = preg_replace ("#<[^/>]+/>#isU", "", $str);
    }
    else {
        $get = preg_replace ("#^(.*)<([^/>]+)>(.*)$#isU","$2",$str,1);

        if ($get == $pagebreak_str)
            $is_below_break = true;
        if (!$is_below_break)
            $str = preg_replace ("#<([^/>]+)>#isU","$weird_replacement$1>",$str,1);
        if (preg_match ("#</([^/>]+)>(.+)(<$pagebreak_str>)#isU", $str))
            $str = preg_replace ("#</([^/>]+)>#isU", "$weird_replacement/$1>", $str, 1);
    }
}
$str = preg_replace ("#$weird_replacement#isU", "<", $str);

echo $str;

此代码假设您没有任何 html 编码错误,例如交叉标记 (<div><a></div></a>),但它肯定使用正确的编码样式。
试试看,享受吧!

于 2012-08-03T21:57:47.990 回答