我希望将标记视为:
<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这样的图书馆似乎过于沉重,似乎应该是一项简单的任务。
答案 0 :(得分:1)
我使用以下函数删除节点而不删除其子节点:
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>
答案 1 :(得分:0)
那么,
根据我的经验,每次使用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(),implode()和array_diff()来完成特定的任务,共同实现目标。
希望它有所帮助。