Regex递归检测空标记

  • 本文关键字:递归 Regex regex
  • 更新时间 :
  • 英文 :


我需要检测所有不包含文本的<p>标记,无论<p>标记包含其他空标记(如<strong>, <em>, <span>…)。然后我需要用&nbsp;实体替换<p>标签的内容。

下面的几个例子:

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

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

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

4 -我不想转换下面的HTML:
<p style="font-size: 16px;"><em>lorem ipsum</em></p>

我已经能够构建一个regex,它只适用于<p>标签中包含的单个标签(或无):

<p([^>]*)>(?:<[^/>][^>]*></[^>]+>)?</p>

我找不到一种方法来使它与<p>标签(例3)中叠叠的几个标签一起工作。

使用一个漂亮的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();
?>

参见 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>

您可以轻松地在DOM结构中使用JavaScript来完成它,顺便说一下,这比使用正则表达式要快得多,因为regex解析整个字符串,当您在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;';
    }
}

好运。

最新更新