如何仅使用preg_replace删除包装器标记。
例如:我想从中删除p标签:
$html = "<p><div><p>aaaaaa</p></div></p>";
输出应为:<div><p>aaaaaa</p></div>
如果输入
$html = "<p>aaaaaa</p><div>bbbb</div>";
输出应为:<p>aaaaaa</p><div>bbbb</div>
我尝试使用此正则表达式:'/<p[^>]*>(.*)<\/p[^>]*>/i'
但它替换了所有p标记。
答案 0 :(得分:0)
这是使用递归模式的正则表达式方法。
代码:(Demo)
$htmls = [
"<p><div><p>aaaaaa</p></div></p>",
"<div><p>aaaaaa</p></div>",
"<p>aaaaaa</p><div>bbbbbb</div>",
"<p>aaaaaa</p><div>bbbbbb</div><p>cccccc</p>",
"<p>aaaaaa</p><p>bbbbbb</p>",
"<p>hello<p>aaaaaa</p></p>",
"<p><p>aaaaaa</p></p>"
];
foreach ($htmls as $i => $html) {
$without_ptags = preg_replace('~<p>(?:(?R)|.*?)*</p>~', '', $html,2, $count);
if ($without_ptags === '' && $count == 1) {
echo "$i => ", substr($html, 3, -4);
}else{
echo "$i => not wrapped in p tags";
}
echo "\n---\n";
}
输出:
0 => <div><p>aaaaaa</p></div>
---
1 => not wrapped in p tags
---
2 => not wrapped in p tags
---
3 => not wrapped in p tags
---
4 => not wrapped in p tags
---
5 => hello<p>aaaaaa</p>
---
6 => <p>aaaaaa</p>
---
*注意不建议使用正则表达式解析HTML。如果我能想出一个聪明的DomDocument方法,我会把它添加到我的答案中。
在此之前,我的代码使用递归模式将<p>...</p>
子串替换为空字符串。 (Pattern Demo)preg_replace()
存储$count
中的替换次数。如果输出字符串完全为空且$count
为1
,则可以推断出html字符串完全嵌套在单个父<p>
标记中。完成此确定后,substr()
用于删除前导<p>
和尾随</p>
。 *注意:使用2
的替换限制,因为无论输出到$without_ptags
,2个或更多替换都会构成不合格的html字符串。