PHP-php trim函数去汉字问题
使用 rtrim 函数 操作utf-8汉字为什么有时候会出现不正常的情况?
echo rtrim("河北省",'省'); //正常输出 河北
echo rtrim("广东省",'省'); //却输出了 广
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用 rtrim 函数 操作utf-8汉字为什么有时候会出现不正常的情况?
echo rtrim("河北省",'省'); //正常输出 河北
echo rtrim("广东省",'省'); //却输出了 广
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(5)
trim,rtrim,ltrim是无法处理汉字的,程序中应该避免这样的处理。
一段测试程序:
echo rawurlencode('河北省');
echo rawurlencode('广东省');
echo rtrim('河北省', '省');
echo rtrim('广东省', '省');
以上程序输出:
%E6%B2%81%E5%8C%97%E7%9C%81
%E5%B9%BF%E4%B8%9C%E7%9C%81
%E6%B2%81%E5%8C%97
%E5%B9%BF%E4%B8
看见端倪了吗?
如果进行操作rtrim('广东省', '省'),省的十六制作表示是e7 9c 81,而东的十六进制表示是e4 b8 9c,都出现了9c,哦~正因为是rtrim,所以rtrim('广东省', '省')的时候把“东”的十六进制表示的最后一位也被trim掉了。同理rtrim('河北省', '省')不存在此问题。
总结:trim类函数禁止用来处理汉字。
由于汉字编码问题导致,可以用这个方法:
/**
+----------------------------------------------------------
* 字符串截取,支持中文和其他编码
+----------------------------------------------------------
+----------------------------------------------------------
* @param string $str 需要转换的字符串
* @param string $length 截取长度
* @param string $start 开始位置
* @param string $charset 编码格式
* @param string $suffix 截断显示字符
+----------------------------------------------------------
* @return string
+----------------------------------------------------------
*/
function cutStr($str, $length, $suffix=true, $start=0, $charset="utf-8") {
$returnstr = '';
$i = 0;
$l = 0;
while ($l<$length) {
$sub = mb_substr($str, $i, 1, $charset);
$i++;
$returnstr .= $sub;
if (strlen($sub)==1) {
$l += (($sub == "r") || ($sub == "n"))?0:0.5;
}
else {
$l++;
}
}
if (mb_strlen($str, $charset) > mb_strlen($returnstr, $charset) && $suffix) {
$returnstr .= ($suffix === true)?'...':$suffix;
}
return $returnstr;
}
有个麻烦点的方法,但是是可行的:
就是在得到字符串的时候在每个省的前边加一个“.”,
然后在进行操作,这样就可以避免你的问题,
可以测试一下:
echo rtrim("河北·省",'省'); //正常输出 河北
echo rtrim("广东·省",'省'); //却输出了 广东
/**
* KenStringHelper 类提供了一组简化字符串操作的方法
*/
class KenStringHelper {
/**
* 截取字符串
*/
static function truncate( $string,$length = 80,$etc='...',$count_words = true ) {
mb_internal_encoding("UTF-8");
if ($length == 0)return '';
if ( strlen( $string ) <= $length ) return $string;
preg_match_all("/[x01-x7f]|[xc2-xdf][x80-xbf]|xe0[xa0-xbf][x80-xbf]|[xe1-xef][x80-xbf][x80-xbf]|xf0[x90-xbf][x80-xbf][x80-xbf]|[xf1-xf7][x80-xbf][x80-xbf][x80-xbf]/", $string, $info);
if( $count_words ){
$wordscut = '';
$j = 0;
for($i=0; $i<count($info[0]); $i++) {
$wordscut .= $info[0][$i];
if( ord( $info[0][$i] ) >=128 ){
$j = $j+2;
}else{
$j = $j + 1;
}
if ($j >= $length ) {
return $wordscut.$etc;
}
}
return join('', $info[0]);
}
return join("",array_slice( $info[0],0,$length ) ).$etc;
}
}
写了一个,可以试试:
function trim_cn($str, $trim, $charset = 'UTF-8') {
$len = mb_strlen($str, $charset);
if (!$len)
return;
$t1 = $t2 = false;$o=$l=0;
for($i=0;$i<$len;$i++)
{
$str1 = mb_substr($str, $i, 1, $charset);
$str2 = mb_substr($str, $len-$i-1, 1, $charset);
if($str1 == $trim && !$t1) $o++; else $t1 = true;
if($str2 == $trim && !$t2) $l++; else $t2 = true;
}
return mb_substr($str, $o, ($len-$l-$o), $charset);;
}