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

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

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 '
'.$len; //return 28

$len = strlen($str2);

echo '
'.$len; //return 29

echo '
';

echo substring($str1, 0, 11);

echo '
';

echo substring($str2, 0, 11);

echo '
';

echo substring($str1, 16, 28);

echo '
';

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;

}

}

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值