PHP DOM - 剥跨度标签,使它们的内容
我期待采取的标记,如:PHP DOM - 剥跨度标签,使它们的内容
<span class="test">Some text that is <strong>bolded</strong> and contains a <a href="#">link</a>.</span>
,并找到在PHP的最佳方法剥离跨度,使剩下的是这样的:
Some text that is <strong>bolded</strong> and contains a <a href="#">link</a>.
我已经阅读了许多有关使用PHP DOM而不是正则表达式解析HTML的其他问题,但一直无法找到一种方法来剥离PHP DOM的跨度,使HTML内容保持不变。最终目标是能够剥离所有span标签的文档,并保留其内容。这可以用PHP DOM完成吗?有没有一种方法可以提供更好的性能,并且不依赖字符串解析而不是DOM解析?
我用正则表达式来做到这一点,没有迄今为止的任何问题:
/<(\/)?(span)[^>]*>/i
但在这里我的兴趣是成为一个更好的PHP程序员。而且,由于它总是可以用格式不正确的标记查找正则表达式,所以我正在寻找更好的方法。我一直在使用用strip_tags()也认为,做类似以下内容:
public function strip_tags($content, $tags_to_strip = array())
{
// All Valid XHTML tags
$valid_tags = array(
'a','abbr','acronym','address','area','b','base','bdo','big','blockquote','body','br','button','caption','cite',
'code','col','colgroup','dd','del','dfn','div','dl','DOCTYPE','dt','em','fieldset','form','h1','h2','h3','h4',
'h5','h6','head','html','hr','i','img','input','ins','kbd','label','legend','li','link','map','meta','noscript',
'object','ol','optgroup','option','p','param','pre','q','samp','script','select','small','span','strong','style',
'sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','ul','var'
);
// Remove each tag to strip from the valid_tags array
foreach ($tags_to_strip as $tag){
$ndx = array_search($tag, $valid_tags);
if ($ndx !== false){
unset($valid_tags[ $ndx ]);
}
}
// convert valid_tags array into param for strip_tags
$valid_tags = implode('><', $valid_tags);
$valid_tags = "<$valid_tags>";
$content = strip_tags($content, $valid_tags);
return $content;
}
但这仍然是解析字符串,而不是DOM解析。因此,如果文本不正确,可能会剥离太多。很多人都很快建议使用Simple HTML DOM Parser,但看看源代码,它似乎也使用正则表达式来解析html。
这可以用PHP5的DOM来完成,还是有更好的方法去除标签,使其内容保持不变。使用Tidy或HTML Purifier来清理文本,然后在其上使用正则表达式/ HTML简单HTML DOM解析器会是不好的做法吗?
像phpQuery这样的库似乎太重了,看起来它应该是一个简单的任务。
我用下面的函数删除一个节点而不删除其孩子:
function DOMRemove(DOMNode $from) {
$sibling = $from->firstChild;
do {
$next = $sibling->nextSibling;
$from->parentNode->insertBefore($sibling, $from);
} while ($sibling = $next);
$from->parentNode->removeChild($from);
}
每例如:
$dom = new DOMDocument;
$dom->load('myhtml.html');
$nodes = $dom->getElementsByTagName('span');
foreach ($nodes as $node) {
DOMRemove($node);
}
echo $dom->saveHTML();
会给你:
Some text that is <strong>bolded</strong> and contains a <a href="#">link</a>.
这枚:
$nodes = $dom->getElementsByTagName('a');
foreach ($nodes as $node) {
DOMRemove($node);
}
echo $dom->saveHTML();
会给你:
<span class="test">Some text that is <strong>bolded</strong> and contains a link.</span>
好,
以我的经验,我每次与DOM的工作时间,我在洛杉矶的表现有点简单STRI操作比较时。
使用您的函数,您试图严格筛选有效的XHTML标记,但由于您可以通过本地函数将所有此任务分配给PHP解释器,因此不需要使用手动比较的循环。
当然,你已经很好地结合在一起,实现了非常好的表现(对我来说,0。0002毫秒),但您可以尝试将功能组合在一行中,从而使每项功能都能完成自己的工作。
看一看,你就会明白我在说什么:
$text = '<span class="test">Some text that is <strong>bolded</strong> and contains a <a href="#">link</a>.</span>';
$validTags = array('a','abbr','acronym','address','area','b','base','bdo','big','blockquote','body','br','button','caption','cite',
'code','col','colgroup','dd','del','dfn','div','dl','DOCTYPE','dt','em','fieldset','form','h1','h2','h3','h4',
'h5','h6','head','html','hr','i','img','input','ins','kbd','label','legend','li','link','map','meta','noscript',
'object','ol','optgroup','option','p','param','pre','q','samp','script','select','small','span','strong','style',
'sub','sup','table','tbody','td','textarea','tfoot','th','thead','title','tr','tt','ul','var'
);
$tagsToStrip = array('span');
var_dump(strip_tags($text, sprintf('<%s>', implode('><', array_diff($validTags, $tagsToStrip)))));
我用自己的列表,但我结合的sprintf(),内爆()和和array_diff()做特定任务共同实现目标。
希望它有帮助。