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

作者:令狐葱 时间:2024-05-11 09:44:55 

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


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 29

echo '<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;
}
}
标签:php,字符串,乱码
0
投稿

猜你喜欢

  • Python执行外部命令subprocess的使用详解

    2023-01-21 14:57:49
  • VS 2008的性能改进

    2007-10-07 21:42:00
  • Node.js 的异步 IO 性能探讨

    2024-05-13 09:58:15
  • K近邻法(KNN)相关知识总结以及如何用python实现

    2022-07-15 17:10:45
  • 如何以及何时使用sIFR

    2008-03-07 12:38:00
  • Python闭包的使用方法

    2022-11-27 07:45:07
  • Layui表格监听行单双击事件讲解

    2024-04-19 10:45:00
  • 基于python使MUI登录页面的美化

    2023-10-23 16:28:03
  • SQL Server触发器及触发器中的事务学习

    2024-01-27 08:48:02
  • 云服务器centos8安装oracle19c的详细教程

    2024-01-23 06:36:23
  • Go语言中并发的工作原理

    2024-05-08 10:13:25
  • mysql5.5数据库data目录迁移方法详解

    2024-01-23 10:56:27
  • 新 API 寻求让 JavaScript 操作本地文件

    2009-11-27 18:28:00
  • ES6入门教程之let、const的使用方法

    2024-05-22 10:36:59
  • 清空所有表中的数据的存储过程

    2024-01-16 11:00:08
  • Python入门基础之变量及字符串

    2023-08-08 06:10:11
  • Python聊天室带界面实现的示例代码(tkinter,Mysql,Treading,socket)

    2024-01-23 21:46:07
  • Pycharm安装第三方库时Non-zero exit code错误解决办法

    2023-03-15 12:15:01
  • python的dataframe转换为多维矩阵的方法

    2021-08-19 08:59:09
  • Django框架配置mysql数据库实现过程

    2024-01-20 00:35:23
  • asp之家 网络编程 m.aspxhome.com