正则表达式递归检测空标签

时间:2016-09-08 16:24:20

标签: regex

我需要检测所有不包含文字的<p>标记,无论<p>标记包含其他空标记(例如<strong><em>,{{1 }} ...)。 然后,我需要用<span>实体替换<p>代码的内容。

以下几个例子:

1 - 我想转换下面的HTML:
&nbsp;
in:
<p style="font-size: 16px;"></p>

2 - 我想转换下面的HTML:
<p style="font-size: 16px;">&nbsp;</p>
in:
<p style="font-size: 16px;"><em></em></p>

3 - 我想转换下面的HTML:
<p style="font-size: 16px;">&nbsp;</p>
in:
<p style="font-size: 16px;"><strong><em></em></strong></p>

4 - 我想要改变下面的HTML:
<p style="font-size: 16px;">&nbsp;</p>

我已经能够构建一个仅适用于<p style="font-size: 16px;"><em>lorem ipsum</em></p>标记中包含的单个标记(或无标记)的正则表达式:

<p>

我找不到一种方法可以使用<p([^>]*)>(?:<[^\/>][^>]*><\/[^>]+>)?<\/p>标签中的几个标签(示例3)来使其工作。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

改为使用漂亮的DOM解析器:

<?php

$data = <<<DATA
<div>
    <p style="font-size: 16px;"></p>
    <p style="font-size: 16px;"><em></em></p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;"><strong><em></em></strong></p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;"><em>lorem ipsum</em></p>
</div>
DATA;

$dom = new DOMDocument();
$dom->loadHTML($data, LIBXML_HTML_NOIMPLIED);
#$dom->removeChild($dom->doctype);

$xpath = new DOMXPath($dom);
$lines = $xpath->query("//p[not(normalize-space())]");
foreach ($lines as $line) {
    while ($line->hasChildNodes()) {
        $line->removeChild($line->firstChild);
    }
    $line->nodeValue = '&nbsp;';
}

echo $dom->saveHTML();
?>

a demo on ideone.com

<小时/> 这会产生:

<div>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;">&nbsp;</p>
    <p style="font-size: 16px;"><em>lorem ipsum</em></p>
</div>

答案 1 :(得分:1)

您可以使用DOM结构中的JavaScript轻松完成它,这比使用正则表达式快得多,因为正则表达式解析整个字符串,当在DOM树中浏览时,您正在寻找已经解析的信息(Element的像textContent这样的数据是静态数据,当你调用它时不会计算它。

var elements = documnet.getElementsByTagName('p'), element, i;
for ( i in elements )
{
    element = elements[i];
    if ( element instanceof HTMLParagraphElement
         && !element.textContent.trim() )
    {
        element.innerHTML = '&nbsp;';
    }
}
祝你好运。