php trim函数去汉字问题

使用 rtrim 函数 操作utf-8汉字为什么有时候会出现不正常的情况?

  
echo rtrim("河北省",'省'); //正常输出 河北
echo rtrim("广东省",'省'); //却输出了 广

为什么有时候正常有时候不正常?

评论 (3)链接2012-01-27 
  • 0 支持
    rtrim是php自带函数,只要你的php程序存储相同的编码格式不应该会出现上面问题呀,我在我本机是了没出现你说的那样,显示正常 – 张洪保 2012-01-30
  • 0 支持
    @张洪保 php文件编码为utf-8 – 冯义军 2012-02-08
  • 0 支持
    @张洪保,你是怎么测试的啊,我的怎么和@phper的情况一样啊 – 崔苔吾 2012-02-29

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类函数禁止用来处理汉字。

该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (2)链接 • 2012-02-29
  • 0 支持
    我想要的解释,非常好的答案。 – 冯义军 2012-02-29
  • 0 支持
    兄弟客气了~ 互帮互助,一起进步 呵呵。以前我也没真正去研究,看见你的提问才有幸深挖一下:-D – soooldier 2012-02-29

由于汉字编码问题导致,可以用这个方法:

  
/**
+----------------------------------------------------------
* 字符串截取,支持中文和其他编码
+----------------------------------------------------------
+----------------------------------------------------------
* @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;
}
小白
小白
1776
编辑于 2012-01-30
该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (0)链接 • 2012-01-29
  
/**
* 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;
}

}
小白
小白
1776
编辑于 2012-01-30
该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (0)链接 • 2012-01-29

有个麻烦点的方法,但是是可行的:
就是在得到字符串的时候在每个省的前边加一个“.”,
然后在进行操作,这样就可以避免你的问题,
可以测试一下:

  
echo rtrim("河北·省",'省'); //正常输出 河北
echo rtrim("广东·省",'省'); //却输出了 广东
该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (0)链接 • 2012-02-29

写了一个,可以试试:

  
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);;
}
该答案已被锁定,无法对其进行评论,编辑及投票。
()
评论 (0)链接 • 2013-11-16
德问是一个专业的编程问答社区,请 登录注册 后再提交答案