从文档中删除空HTML

时间:2011-12-22 15:52:43

标签: php regex

我需要帮助在HTML中删除空标记。这里有一个解决方案:

Remove empty tags using RegEx

但我不能使用JS,and I should never use Regular expressions to parse HTML

我需要用PHP清理输入,而且我还需要获得的不仅仅是空标记。

我还需要抓住这样的标签:

<p> </p> (variable whitespace with nothing in the tag)
<p>&nbsp;</p>
<p><br/><p>
<p><br /></p>

在进入数据库(WYSIWYGs)之前,我该怎么做才能捕获这样的坏标记?

3 个答案:

答案 0 :(得分:4)

使用a document object model parser解析它,检查节点的文本内容,删除不符合条件的节点(解析为脚本标记,包含空格,是iframe等)。

评论部分还有很多示例代码。

这里有一堆代码可以做类似的事情(从php.net上的随机剪切+粘贴中采用)

<?php

$sampleHTML = "
<p>  </p>
<p> &nbsp;   <p>
<p><br/></p>
<p><br /></p>
<span>Non-empty span<p id='NestedEmptyElement'></p></span>
";

$doc = new DOMDocument();
$doc->loadHTML($sampleHTML);
$domNodeList = $doc->getElementsByTagname('*');
$domElemsToRemove = array();
foreach ( $domNodeList as $domElement ) {
  $domElement->normalize();
  if (trim($domElement->textContent, "\xc2\xa0 \n \t ") == "") {
    $domElemsToRemove[] = $domElement;
  }
}

foreach( $domElemsToRemove as $domElement ){
    try {
      $domElement->parentNode->removeChild($domElement);
    } catch (Exception $e) {
      //node was already deleted.
      //There's a better way to do this, it's recursive.
    }
}


$domNodeList = $doc->getElementsByTagname('body')->item(0);
$childNodes = $domNodeList->childNodes;

foreach ( $childNodes as $domElement ) {
  echo trim($domElement->C14N());
}

echo "\n\n";

然后我们跑..

$ php foo.php -v
<span>Non-empty span</span>

答案 1 :(得分:2)

这符合你的例子和更多:

^<p>\s*(?:(?:&nbsp;|<br\s*/>)\s*)*</p>$

但是你只关注p标签吗?每行可以有几个吗?

normal* (special normal*)*的另一个用途是:

  • 正常:\s
  • 特殊:(&nbsp;|<br\s*/>)

(非捕获组)

答案 2 :(得分:0)

我在这方面工作了大约一天,并且看到很多“我不同意使用正则表达式”。

但是我在DOMDocument弄乱了我的html实体时遇到了很大的问题。我会仔细过滤文本,以便所有TM符号都转换为HTML实体,例如&amp; trade;但它会将它们转换回TM符号。

我一直在与防止这种行为作斗争。为此提到了一些黑客攻击。经过一天的战斗后,我想“为什么我要努力工作才能破解它?它应该工作......”然后我在10分钟内使用simplehtmldom编写了这个函数:

function stripEmptyTags($html){
    $dom = new simple_html_dom();
    $dom->load($html);
    foreach($dom->find("*") as $e)
        if( trim( str_replace( array(' ','&nbsp;'), "", $e->innertext )) == "" ) 
            $e->outertext = "";
    $dom->load($dom->save());
    return $dom->save();
}