php只删除包装标签

时间:2018-02-21 10:21:40

标签: php regex preg-replace

如何仅使用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标记。

1 个答案:

答案 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 Demopreg_replace()存储$count中的替换次数。如果输出字符串完全为空且$count1,则可以推断出html字符串完全嵌套在单个父<p>标记中。完成此确定后,substr()用于删除前导<p>和尾随</p>。 *注意:使用2的替换限制,因为无论输出到$without_ptags,2个或更多替换都会构成不合格的html字符串。