2011-04-19 49 views
6

的前500个字符我有一个​​巨大的HTML代码,就像一个PHP变量: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结构。

是否有任何tuorial或工作示例可用?

+0

您是否希望将文本计算为不使用html,但随后返回包装在原始html中? – 2011-04-19 04:09:22

+0

是的。我希望它被包裹在html中,以便我可以在页面上显示它。 – Vin 2011-04-19 09:00:32

+0

我在前面的答案中添加了一些伪元素 - 希望它能指引您朝着正确的方向发展。我真的很抱歉,我没有时间去做正确的工作,但通过交叉手指会让你渡过难关。发布你的答案,如果你拿出解决方案!我很想看。 – 2011-04-20 18:02:07

回答

3

Ooohh喔...我知道这一点,我不能让它正好把我的头顶部,但要加载你已经有了一个DOM文档文本

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

然后抓住来自整个文档节点的文本(作为DOM节点http://www.php.net/manual/en/class.domnode.php

这并不完全正确,但希望这会引导您走上正确的轨道。 试着这么做:

​​

编辑确定...应该工作。只是本地

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; 
    } 
+0

'textContent'是一个属性。另外,这不是所有的HTML都被剥离了吗? – alex 2011-04-19 04:04:36

4

如果你想要的文字,你可以用下面的太

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

我需要HTML格式的输出字符串,我可以在HTML页面上显示它。 – Vin 2011-04-19 09:03:13

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. 
} 
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。