Php 获取非空元素的HTML内容

Php 获取非空元素的HTML内容,php,html,domdocument,Php,Html,Domdocument,目前我有这种混乱,没有问如何: $string = " <p> <b>Foo1:</b> Bar1<br> <b>Foo2:</b> Bar2<br> <b>Foo3:</b> Bar3<br> <b>Foo4:</b> Bar4 </p> <br> <p></p> <

目前我有这种混乱,没有问如何:

$string = "
<p>
    <b>Foo1:</b> Bar1<br>
    <b>Foo2:</b> Bar2<br>
    <b>Foo3:</b> Bar3<br>
    <b>Foo4:</b> Bar4
</p>
<br>
<p></p>
<br>
<p>
</br>
<br />
<br/>
<br>
</p>
"
$string=”

Foo1:Bar1
Foo2:Bar2
Foo3:Bar3
Foo4:Bar4







"
所以我需要像这样修剪所有的

$string = "
<p>
    <b>Foo1:</b> Bar1<br>
    <b>Foo2:</b> Bar2<br>
    <b>Foo3:</b> Bar3<br>
    <b>Foo4:</b> Bar4
</p>
"
$chars = " \t\n\r\0\x0B";
$subpattern = '(</?(br|p) ?/?[^>]*>)';
$pattern = '~(^'.$subpattern.'|'.$subpattern.'$)~i';

trim(preg_replace($pattern, '', $string), $chars)
$string=”

Foo1:Bar1
Foo2:Bar2
Foo3:Bar3
Foo4:Bar4

"
我试着这样做:

$string = "
<p>
    <b>Foo1:</b> Bar1<br>
    <b>Foo2:</b> Bar2<br>
    <b>Foo3:</b> Bar3<br>
    <b>Foo4:</b> Bar4
</p>
"
$chars = " \t\n\r\0\x0B";
$subpattern = '(</?(br|p) ?/?[^>]*>)';
$pattern = '~(^'.$subpattern.'|'.$subpattern.'$)~i';

trim(preg_replace($pattern, '', $string), $chars)
$chars=“\t\n\r\0\x0B”;
$subpattern='(]*>)';
$pattern='~(^.$subpattern.|'.$subpattern.$)~i';
修剪(预替换($pattern,,$string),$chars)

但它只删除最后一个
,我如何才能使它正常工作?

使用strip\u标签功能

与其尝试正则表达式方法,不如尝试解析HTML,然后丢弃空元素,因为这实际上是您想要实现的。类似于DOMDocument::loadHTML()的内容将为您提供一个数组结构,您可以在删除不需要的部分后循环,然后转换回HTML。

使用DOMDocument和DOMXPath的方法:

function isEmpty($n) {
    $nodeList = $n[0]->childNodes;
    foreach ($nodeList as $childNode) {
        switch ( $childNode->nodeType ) {
            case XML_ELEMENT_NODE:
                if ( !in_array($childNode->nodeName, ["p", "br"]) ||
                     $childNode->nodeName == "p" && !isEmpty([$childNode]) ) return false;
            case XML_TEXT_NODE:
                if ( trim($childNode->nodeValue) !== "" ) return false;
        }
    }
    return true;
}

$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($string);
$xp = new DOMXPath($dom);
$xp->registerNamespace("php", "http://php.net/xpath");
$xp->registerPHPFunctions('isEmpty');

$nodeList = $xp->query('//br[not(./ancestor::p)] | //p[php:function("isEmpty", .)]');

foreach ($nodeList as $node) {
    $node->parentNode->removeChild($node);
}

foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $childNode) {
    echo $dom->saveHTML($childNode);
}

您应该使用
DOMDocument
,而不是使用
regex
解析
HTML
,这里我们只是使用
/p/b/查询
DOMDocument


OP想删除一些相同类型的标记,但不想删除其他标记,所以我不确定这是否合适。@LornaMitchell是的,你是对的。顺便说一句,我非常喜欢您在PHPNW中的演示:)好吧,使用
strip_tags()
可以工作,但是您必须将您想要的所有标记都列为白名单,而不是仅仅禁止您不想要的标记。这可能会带来更多的问题,而不是它的帮助,正则表达式可能是最好的选择。谢谢,它工作完美无瑕。如何将最大换行限制为5<代码>如果(+$i==5)中断对我无效:s