删除HTML字符串中的空标记(非自动关闭)

时间:2014-08-20 22:28:59

标签: php html regex tags domdocument

有谁知道如何用PHP删除空标签?

  • 应忽略自闭标签
  • 应考虑空内容(空格,换行符等)

我确实尝试了两件事:

使用DOMdocument,但问题是它将自关闭标记视为空(图像等)

$xpath = new DOMXPath($dom);
$query = '//*[not(node())]'; //all empty tags
$nodes = $xpath->query($query);

foreach ($nodes as $node) {
    $node->parentNode->removeChild($node);
}

我也尝试过正则表达式,但我在互联网上找到的最好的一个并不能满足我的需求:

//http://regex101.com/r/rD0sI8/1
$pattern = "/<.[^>]*>(\s+|()|(&nbsp;)*|\s+(&nbsp;)*|(&nbsp;)*\s+|\s+(&nbsp;)*\s+)<\/.[^>]*>/i"; 
$content = preg_replace($pattern,'',$content);

我猜它有问题

<img...></span>
例如,

。这就是为什么我更喜欢使用DOMdocument ......

有什么想法吗?

3 个答案:

答案 0 :(得分:0)

如果要删除空标记,可以使用此正则表达式:

<(.*?)\s*.*?>\s*<\/\1>

<强> Working demo

答案 1 :(得分:0)

如果可用或您可以安装它,则可以使用[php-tidy][1]扩展名。这应该摆脱你的空标签并修复其他错误。

A simple example

答案 2 :(得分:0)

要处理嵌套的空元素,您可以运行preg_replace,直到没有任何内容可以替换:

<?php

$html = 'foo <i></i> bar <img src> <img> <ul><li></li></ul>';

do {
  $input = $html;
  $html = preg_replace('/<(\S+)[^>]*><\/\1>/', '', $input);
} while ($html !== $input);

print $html;

鉴于使用正则表达式解析HTML总是会导致问题,但最好使用DOM来删除a)不是known "void" elements in HTML而b)没有文本内容的节点:

<?php

$html = '<div>foo <i></i> bar <img src> <img> <ul><li></li></ul></div>';

$doc = new DOMDocument;
$doc->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($doc);
$nodes = $xpath->query('//node()');

$voids = array('area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr');

foreach ($nodes as $node) {
  if (!in_array($node->nodeName, $voids) && !strlen($node->textContent)) {
    $node->parentNode->removeChild($node);
  }
}

print $doc->saveHTML(); //  <div>foo  bar <img src> <img> </div>