首页 > 语言 > PHP > 正文

PHP中文字符串截断无乱码解决方法

2024-05-04 23:50:51
字体:
来源:转载
供稿:网友

一个比较好用的字符串截取函数:

function substring($str, $start, $length){ //比较好用字符串截取函数  $len = $length;  if($length < 0){  $str = strrev($str);  $len = -$length;  }  $len= ($len < strlen($str)) ? $len : strlen($str);  $tmpstr = "";  for ($i= $start; $i < $len; $i ++)  {      if (ord(substr($str, $i, 1)) > 0xa0)      {       $tmpstr .= substr($str, $i, 2);       $i++;      } else {       $tmpstr .= substr($str, $i, 1);      }  }  if($length < 0) $tmpstr = strrev($tmpstr);  return $tmpstr;}

使用方法示例:

$str1 = '我是一串比较长的中文不带英文';$str2 = '我是一串比较长的中文带yingwen';$len = strlen($str1);echo '<br />'.$len; //return 28$len = strlen($str2);echo '<br />'.$len; //return 29echo '<br />';  echo substring($str1, 0, 11);  echo '<br />';echo substring($str2, 0, 11);    echo '<br />';echo substring($str1, 16, 28);  echo '<br />';echo substring($str2, 16, 29);  

结果显示:

28
29
我是一串比较
我是一串比较
中文不带英文
中文带yingwen

这个函数十分有用,比如用来截断比较长的文件名,但是要在中间加上...,可以这样来做:

function formatName($str, $size){  $len = strlen($str);  if(strlen($str) > $size) {    $part1 = substring($str, 0, $size / 2);    $part2 = substring($str, $len - ($size/2), $len);    return $part1 . "..." . $part2;  } else {    return $str;  }}

另外,网上看到一种超级简单的中文截断解决方案,试用了一下,效果也不错:

echo substr($str1,0,10).chr(0);

原理解释:

chr(0)不是null
07null是什么都没有,而chr(0)的值是0。表示成16进制是0x00,表示成二进制是00000000
08虽然chr(0)不会显示出什么,但是他是一个字符。
09当汉字被截断时,根据编码规则他总是要把后边的其他字符拉过来一起作为汉字解释,这就是出现乱码的原因。而值为0x81到0xff与0x00组合始终都显示为“空”
10根据这一特点,在substr的结果后面补上一个chr(0),就可以防止出现乱码了

----------------------------

20120705更新: 

以上方法虽好,但是偶尔还是会碰到乱码,原因未深究。不过可以用以下的方法,对UTF8字符文本屡试不爽。
注意:该方法中将汉字计算为1单位长度,英文一个字母1单位长度,所以截断时需要注意长度设置。
计算长度的方法:

function strlen_UTF8($str){  $len = strlen($str);  $n = 0;  for($i = 0; $i < $len; $i++) {    $x = substr($str, $i, 1);    $a = base_convert(ord($x), 10, 2);    $a = substr('00000000'.$a, -8);    if (substr($a, 0, 1) == 0) {    }elseif (substr($a, 0, 3) == 110) {      $i += 1;    }elseif (substr($a, 0, 4) == 1110) {      $i += 2;    }    $n++;  }  return $n;} // End strlen_UTF8;

字符串截断函数:

function subString_UTF8($str, $start, $lenth)  {    $len = strlen($str);    $r = array();    $n = 0;    $m = 0;    for($i = 0; $i < $len; $i++) {      $x = substr($str, $i, 1);      $a = base_convert(ord($x), 10, 2);      $a = substr('00000000'.$a, -8);      if ($n < $start){        if (substr($a, 0, 1) == 0) {        }elseif (substr($a, 0, 3) == 110) {          $i += 1;        }elseif (substr($a, 0, 4) == 1110) {          $i += 2;        }        $n++;      }else{        if (substr($a, 0, 1) == 0) {          $r[ ] = substr($str, $i, 1);        }elseif (substr($a, 0, 3) == 110) {          $r[ ] = substr($str, $i, 2);          $i += 1;        }elseif (substr($a, 0, 4) == 1110) {          $r[ ] = substr($str, $i, 3);          $i += 2;        }else{          $r[ ] = '';        }        if (++$m >= $lenth){          break;        }      }    }    return join($r);  } // End subString_UTF8;

使用方法和之前介绍的一样,比如formatName可以实现如下(这对汉字长度做了小优化):

function formatName($str, $size){ $len = strlen_UTF8($str); $one_len = strlen($str); $size = $size * 1.5 * $len / ($one_len); if(strlen_UTF8($str) > $size) {  $part1 = subString_UTF8($str, 0, $size / 2);  $part2 = subString_UTF8($str, $len - ($size/2), $len);  return $part1 . "..." . $part2; } else {  return $str; }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VeVb武林网。


注:相关教程知识阅读请移步到PHP教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选