我从Response获得的这个HTML。
我需要删除多余的文字。
以下内容有一行
<?php
$str = <<<HTML
AAAA <span>span txt</span>
<div class='unique_div' id='xrz' data-id='1'>
div text
<span>span text</span>
<p class='unique_p'>
<span>p span text</span>
<p>p p text</p>
</p>
div text
</div>
BBBB <span>span txt</span>
HTML;
如何替换里面的p上的div?
我需要编写一个正则表达式来获得以下结果
<?php
$str = <<<HTML
AAAA <span>span txt</span>
<p class='unique_p'>
<span>p span text</span>
<p>p p text</p>
</p>
BBBB <span>span txt</span>
HTML;
只有一个div和p具有这样的属性。
答案 0 :(得分:1)
由于您正在查看看似HTML的内容,并且鉴于您的要求需要对Document Object Model (DOM)进行某种形式的修改,我建议使用像DOMDocument
这样的DOM解析器。
如果我正确理解了您的问题,那么您希望将具有<div>
属性id
的{{1}}节点替换为具有xrz
节点的p
节点类属性unique_p
,是div
的子级。
div
非常简单,因为它有id
且它们是唯一的。因此,我们可以使用DOMDocument::getElementById
之类的方法来获取div
。p
变得有点棘手,因为我们要确保它既是div
的孩子又具有指定的类。因此,我们将使用XPath依赖DOMXPath
查询。DOMNode::replaceChild
替换div
与其捕获的孩子p
。这是一个简单的例子。
$str = <<<HTML
AAAA <span>span txt</span>
<div class='unique_div' id='xrz' data-id='1'>
div text
<span>span text</span>
<p class='unique_p'>
<span>p span text</span>
<p>p p text</p>
</p>
div text
</div>
BBBB <span>span txt</span>
HTML;
libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML($str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($dom);
$children = $xpath->query('//div/p[@class="unique_p"]');
$p = $children->item(0);
$div = $dom->getElementById('xrz');
$div->parentNode->replaceChild($p, $div);
echo $dom->saveHTML();
输出看起来应该是这样的。
<p>AAAA <span>span txt</span> <p class="unique_p"> <span>p span text</span> </p><p> BBBB <span>span txt</span></p></p>
如果您想知道为什么输出可能与您预期的略有不同,请务必注意您的问题中提供的初始HTML实际上是格式错误。
See section 9.3.1 of the HTML 4.01 specification
P
元素代表一个段落。它不能包含块级元素(包括P
本身)。
因此,每当DOM解析器在另一个p
标记内找到一个开放的p
标记时,它就会先隐式关闭前一个标记。