我需要截断字符串到指定的长度,忽略HTML标记。我在这里找到了合适的函数
所以我对它做了轻微的改变,添加了缓冲输入ob_start();
问题在于UTF-8。如果截断字符串的最后一个符号是from区间[ą、čę、ėį,š,ų,ū,ž],然后我得到替换字符U + FFFD�
这是我的代码。你可以复制粘贴,然后自己试试:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>String truncate</title>
</head>
<?php
$html = '<b>Koks nors tekstas</b>. <p>Lietuviškas žodis.</p>';
$html = html_truncate(27, $html);
echo $html;
/* Truncate HTML, close opened tags
*
* @param int, maxlength of the string
* @param string, html
* @return $html
*/
function html_truncate($maxLength, $html){
$printedLength = 0;
$position = 0;
$tags = array();
ob_start();
while ($printedLength < $maxLength && preg_match('{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}', $html, $match, PREG_OFFSET_CAPTURE, $position)){
list($tag, $tagPosition) = $match[0];
// Print text leading up to the tag.
$str = substr($html, $position, $tagPosition - $position);
if ($printedLength + strlen($str) > $maxLength){
print(substr($str, 0, $maxLength - $printedLength));
$printedLength = $maxLength;
break;
}
print($str);
$printedLength += strlen($str);
if ($tag[0] == '&'){
// Handle the entity.
print($tag);
$printedLength++;
}
else{
// Handle the tag.
$tagName = $match[1][0];
if ($tag[1] == '/'){
// This is a closing tag.
$openingTag = array_pop($tags);
assert($openingTag == $tagName); // check that tags are properly nested.
print($tag);
}
else if ($tag[strlen($tag) - 2] == '/'){
// Self-closing tag.
print($tag);
}
else{
// Opening tag.
print($tag);
$tags[] = $tagName;
}
}
// Continue after the tag.
$position = $tagPosition + strlen($tag);
}
// Print any remaining text.
if ($printedLength < $maxLength && $position < strlen($html))
print(substr($html, $position, $maxLength - $printedLength));
// Close any open tags.
while (!empty($tags))
printf('</%s>', array_pop($tags));
$bufferOuput = ob_get_contents();
ob_end_clean();
$html = $bufferOuput;
return $html;
}
?>
<body>
</body>
</html>
这个函数的结果看起来像这样:
kks nors tekstas.
Lietuvi�
知道为什么这个函数在使用UTF-8时会出错吗?
知道为什么这个函数在使用UTF-8时会出错吗?
一般的问题是该函数不处理UTF-8字符串,而是处理US-ASCII、Latin-1或任何其他单字节字符集的字符串。
您正在寻找使函数与UTF-8字符集兼容。UTF-8是一个多字节字符集。
为此,有必要验证该函数内部使用的每个字符串函数是否正确处理UTF-8多字节字符集:
-
preg_match
需要一个带有u
修饰符Docs的模式来处理UTF-8字符串。 -
substr
需替换为mb_substr
Docs -
strlen
需要替换为mb_strlen
Docs
当你处理HTML时,使用DOMDocument
来操作HTML块可能更节省。提醒一下,它更灵活,工作也更正常。
我建议简单地使用unicode安全的子字符串函数,例如mb_substr(),来截断unicode字符串。
所以基本上尝试用mb_substr()
替换所有substr()
的出现。
在此之前,检查mbstring PHP模块是否在您的环境中启用。
你要找的
:
mb_strlen()
和关联的函数
只需使用以下函数
echo utf8_encode($match[0])//$match[0]这是你想要打印的变量