strip_tags或preg_replace从html中删除几个标签?

时间:2014-05-27 21:22:08

标签: preg-replace strip-tags

我在这两者之间处于两难境地。 我想从我通过head导入的网页中删除body标记(以及包含doctype / html之前/之前的所有内容),script标记和curl标记。 所以首先想到的是这个

$content = strip_tags($content, '<img><p><a><div><table><tbody><th><tr><td><br><span><h1><h2><h3><h4><h5><h6><code><pre><b><strong><ol><ul><li><em>'.$tags);

正如您所看到的,使用HTML5标签,视频对象等可以获得更长时间。

比我在这看到的还要多。 https://stackoverflow.com/a/16377509/594423

任何人都可以建议首选方法或显示您这样做的方式,请解释原因和 可能告诉我哪一个更快。

谢谢!

1 个答案:

答案 0 :(得分:1)

你可以测试类似的东西:

$dom = new DOMDocument();
@$dom->loadHTML($content);

$result = '';

$bodyNode = $dom->getElementsByTagName('body')->item(0);

$scriptNodes = $bodyNode->getElementsByTagName('script');
$toRemove = array();

foreach ($scriptNodes as $scriptNode) {
    $toRemove[] = $scriptNode;
}

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

$bodyChildren = $bodyNode->childNodes;

foreach($bodyChildren as $bodyChild) {
    $result .= $dom->saveHTML($bodyChild);
}

DOM方法的优点是针对几个html陷阱的相对可靠性,尤其是一些格式错误的标记或javascript字符串中的标记:var str = "<body>";

但速度呢?

如果您使用正则表达式方法,例如:

$pattern = <<<'EOD'
~
<script[^>]*> (?>[^<]++|<(?!/script>))* </script>
|
</body>.*$
|
^ (?>[^<]++|<(?!body\b))* <body[^>]*>
~xis
EOD;

$result = preg_replace($pattern, '', $content);

结果快一点(对于400行的html文件,从1x到2x)。但是使用这段代码,可靠性会降低。

如果速度很重要且如果您对html质量有一个了解,那么可靠性水平与正则表达式相同,您可以使用:

$offset = stripos($content, '<body');
$offset = strpos($content, '>', $offset);
$result = strrev(substr($content,++$offset));
$offset = stripos($result, '>ydob/<');
$result = substr($result, $offset+7);
$offset = 0;
while(false !== $offset = stripos($result, '>tpircs/<', $offset)) {
    $soffset = stripos($result, 'tpircs<', $offset);
    $result = substr_replace($result, '', $offset, $soffset-$offset+7);
}
$result = strrev($result);

比DOM版本快2到5倍。