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()做特定任务共同实现目标。

希望它有帮助。