我在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结构。
是否有任何课程或工作示例?
答案 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.
}