PHP:显示HTML的前500个字符

时间:2011-04-19 03:47:46

标签: php dom domdocument

我在PHP变量中有一个巨大的HTML代码,如:

$html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';

我想只显示此代码的前500个字符。此字符数必须考虑HTML标记中的文本,并在测量长度时排除HTMl标记和属性。 但是在修改代码时,它不应该影响HTML代码的DOM结构。

是否有任何课程或工作示例?

4 个答案:

答案 0 :(得分:4)

如果是您想要的文字,您也可以使用以下内容

substr(strip_tags($html_code),0,500);

答案 1 :(得分:3)

噢......我知道我无法完全摆脱头脑,但你想加载你作为DOMDOCUMENT获得的文本

http://www.php.net/manual/en/class.domdocument.php

然后从整个文档节点中获取文本(作为DOMnode http://www.php.net/manual/en/class.domnode.php

这不完全正确,但希望这会引导你走上正轨。 尝试类似:

 $html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';
 $dom = new DOMDocument();
 $dom->loadHTML($html_code);
 $text_to_strip = $dom->textContent;
 $stripped = mb_substr($text_to_strip,0,500);
 echo "$stripped";  // The Sameple text.Another sample text.....

修改确定...应该可行。刚刚在本地测试

edit2

既然我明白你想保留标签,但限制文字,让我们看看。您将要循环内容,直到达到500个字符。这可能需要一些编辑和通过才能让我做对,但希望我能提供帮助。 (对不起,我不能全神贯注)

第一种情况是文本少于500个字符。没什么好担心的。从上面的代码开始,我们可以执行以下操作。

  if (strlen($stripped) > 500) {
       // this is where we do our work.

       $characters_so_far = 0;
       foreach ($dom->child_nodes as $ChildNode) {

          // should check if $ChildNode->hasChildNodes();
          // probably put some of this stuff into a function
          $characters_in_next_node += str_len($ChildNode->textcontent);
          if ($characters_so_far+$characters_in_next_node > 500) { 
              // remove the node 
              // try using 
              // $ChildNode->parentNode->removeChild($ChildNode);
          } 
          $characters_so_far += $characters_in_next_node
       }
       // 
       $final_out = $dom->saveHTML();
  } else {
        $final_out = $html_code;
  }

答案 2 :(得分:2)

我在php课程下面粘贴我写了时间之前,但我知道它有效。它不完全是你所追求的,因为它处理单词而不是字符数,但我认为它非常接近,有人可能会发现它很有用。

  class HtmlWordManipulator
  {
    var $stack = array();

    function truncate($text, $num=50) 
    { 
      if (preg_match_all('/\s+/', $text, $junk) <= $num) return $text; 
      $text = preg_replace_callback('/(<\/?[^>]+\s+[^>]*>)/','_truncateProtect', $text); 
      $words = 0; 
      $out = array();
      $text = str_replace('<',' <',str_replace('>','> ',$text));
      $toks = preg_split('/\s+/', $text);
      foreach ($toks as $tok) 
      { 
        if (preg_match_all('/<(\/?[^\x01>]+)([^>]*)>/',$tok,$matches,PREG_SET_ORDER))  
          foreach ($matches as $tag) $this->_recordTag($tag[1], $tag[2]);  
        $out[] = trim($tok);
        if (! preg_match('/^(<[^>]+>)+$/', $tok))
        {
          if (!strpos($tok,'=') && !strpos($tok,'<') && strlen(trim(strip_tags($tok))) > 0) 
          {
           ++$words; 
          }
          else
          {                 
            /*
            echo '<hr />';
            echo htmlentities('failed: '.$tok).'<br /)>'; 
            echo htmlentities('has equals: '.strpos($tok,'=')).'<br />';
            echo htmlentities('has greater than: '.strpos($tok,'<')).'<br />';
            echo htmlentities('strip tags: '.strip_tags($tok)).'<br />';
            echo str_word_count($text);
            */
          } 
        }
        if ($words > $num) break; 
      } 
      $truncate = $this->_truncateRestore(implode(' ', $out));   
      return $truncate; 
    }

    function restoreTags($text)
    {
      foreach ($this->stack as $tag) $text .= "</$tag>";
      return $text;
    } 

    private function _truncateProtect($match) 
    { 
      return preg_replace('/\s/', "\x01", $match[0]); 
    } 

    private function _truncateRestore($strings) 
    { 
      return preg_replace('/\x01/', ' ', $strings); 
    }

    private function _recordTag($tag, $args) 
    { 
      // XHTML 
      if (strlen($args) and $args[strlen($args) - 1] == '/') return; 
      else if ($tag[0] == '/') 
      { 
        $tag = substr($tag, 1); 
        for ($i=count($this->stack) -1; $i >= 0; $i--) { 
         if ($this->stack[$i] == $tag) { 
           array_splice($this->stack, $i, 1); 
           return; 
         } 
        } 
        return; 
      } 
      else if (in_array($tag, array('p', 'li', 'ul', 'ol', 'div', 'span', 'a'))) 
        $this->stack[] = $tag;  
      else return;
    } 
  }

truncate就是你想要的,你传递html和你想要剪裁的单词数量。它在计算单词时忽略了html,但随后重写了html中的所有内容,甚至因截断而关闭了尾随标记。

请不要因完全缺乏oop原则来判断我。我年轻而愚蠢。

编辑:

所以事实证明用法更像是这样:

$content = $manipulator->restoreTags($manipulator->truncate($myHtml,$numOfWords));

愚蠢的设计决定。允许我在未关闭的标签内注入html。

答案 3 :(得分:1)

我不打算编写一个真正的解决方案,但如果有人愿意,这就是我要做的事情(在伪PHP中):

$html_code = '<div class="contianer" style="text-align:center;">The Sameple text.</div><br><span>Another sample text.</span>....';
$aggregate = '';

$document = XMLParser($html_code);

foreach ($document->getElementsByTagName('*') as $element) {
  $aggregate .= $element->text(); // This is the text, not HTML. It doesn't
                                  // include the children, only the text
                                  // directly in the tag.
}