【问题标题】:Strip tag with class in PHP在 PHP 中使用类剥离标签
【发布时间】:2011-04-12 19:03:47
【问题描述】:

所以我需要去除tip 类的span 标签。 所以那将是<span class="tip"> 和相应的</span>,以及其中的所有内容......

我怀疑需要一个正则表达式,但我非常讨厌这个。


笑...

<?php
$string = 'April 15, 2003';
$pattern = '/(\w+) (\d+), (\d+)/i';
$replacement = '${1}1,$3';
echo preg_replace($pattern, $replacement, $string);
?>

没有错误...但是

<?php
$str = preg_replace('<span class="tip">.+</span>', "", '<span class="rss-title"></span><span class="rss-link">linkylink</span><span class="rss-id"></span><span class="rss-content"></span><span class=\"rss-newpost\"></span>');
echo $str;
?>

给我错误:

Warning: preg_replace() [function.preg-replace]: Unknown modifier '.' in <A FILE> on line 4

以前,错误出现在第二行的);,但现在.... >.>

【问题讨论】:

  • 嗯,正确的方法是使用 DOM 解析器 - 它也适用于您的“以及其中的所有内容”要求。
  • Recursively loop through the DOM tree and remove unwanted tags? 的可能副本我冒昧地将其标记为副本,即使它不是一个 100%。您必须在删除之前测试所需的标签和类名。
  • 那不好。该方法不允许我检查课程。而且我无法删除所有spans。
  • 你在说什么?当然,该方法允许您检查类。 if $node-&gt;class == "tip" ... 我不明白为什么它不应该删除所有 spans`?

标签: php


【解决方案1】:

这是“正确”的方法(改编自this answer)。

输入:

<?php
$str = '<div>lol wut <span class="tip">remove!</span><span>don\'t remove!</span></div>';
?>

代码:

<?php
function recurse(&$doc, &$parent) {
   if (!$parent->hasChildNodes())
      return;

   for ($i = 0; $i < $parent->childNodes->length; ) {
      $elm = $parent->childNodes->item($i);
      if ($elm->nodeName == "span") {
         $class = $elm->attributes->getNamedItem("class")->nodeValue;
         if (!is_null($class) && $class == "tip") {
            $parent->removeChild($elm);
            continue;
         }
      }

      recurse($doc, $elm);
      $i++;
   }
}

// Load in the DOM (remembering that XML requires one root node)
$doc = new DOMDocument();
$doc->loadXML("<document>" . $str . "</document>");

// Iterate the DOM
recurse($doc, $doc->documentElement);

// Output the result
foreach ($doc->childNodes->item(0)->childNodes as $node) {
   echo $doc->saveXML($node);
}
?>

输出:

<div>lol wut <span>don't remove!</span></div>

【讨论】:

  • 有效的 HTML 内容(full 或 sn-p)可能不是 XML 有效的,因此您的解析可能会失败。
  • 如果您有一个实际的、完整的 HTML 文档,您可以使用 loadHTML 加载它。否则,强硬的 noogie。
【解决方案2】:

一个简单的正则表达式,如:

<span class="tip">.+</span>

不会工作,问题是如果在尖端跨度内打开和关闭另一个跨度,您的正则表达式将以它的结尾终止,而不是尖端一个。像 cmets 中链接的基于 DOM 的工具确实会提供更可靠的答案。

根据我在下面的评论,在 PHP 中使用正则表达式时需要添加模式分隔符。

<?php
$str = preg_replace('\<span class="tip">.+</span>\', "", '<span class="rss-title"></span><span class="rss-link">linkylink</span><span class="rss-id"></span><span class="rss-content"></span><span class=\"rss-newpost\"></span>');
echo $str;
?>

可能会比较成功。请查看相关功能的文档页面。

【讨论】:

  • 好的,那么如何将这个正则表达式应用于我的字符串? xD
  • 您可能会使用 preg_replace() 将匹配的字符串替换为空字符串(空字符串)。不要忘记您需要正则表达式分隔符,us3.php.net/preg_replace 上的示例使用正斜杠作为分隔符。
  • 我对那个功能有疑问。它不起作用。它在关闭参数时抱怨错误();)...
  • 请查看此线程中的第三条评论,或我的更新答案。
  • 如果标签包含 any 其他属性,则会中断。您还忘记了正则表达式分隔符。
【解决方案3】:

现在没有正则表达式,也没有繁重的 XML 解析:

$html = ' ... <span class="tip"> hello <span id="x"> man </span> </span> ... ';
$tag = '<span class="tip">';
$tag_close = '</span>';
$tag_familly = '<span';

$tag_len = strlen($tag);

$p1 = -1;
$p2 = 0;
while ( ($p2!==false)  && (($p1=strpos($html, $tag, $p1+1))!==false) ) {
  // the tag is found, now we will search for its corresponding closing tag
  $level = 1;
  $p2 = $p1;
  $continue = true; 
  while ($continue) {
     $p2 = strpos($html, $tag_close, $p2+1);
     if ($p2===false) {
       // error in the html contents, the analysis cannot continue
       echo "ERROR in html contents";
       $continue = false;
       $p2 = false; // will stop the loop
     } else {
       $level = $level -1;
       $x = substr($html, $p1+$tag_len, $p2-$p1-$tag_len);
       $n = substr_count($x, $tag_familly);
       if ($level+$n<=0) $continue = false;
     }
  }
  if ($p2!==false) {
    // delete the couple of tags, the farest first
    $html = substr_replace($html, '', $p2, strlen($tag_close));
    $html = substr_replace($html, '', $p1, $tag_len);
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2014-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多