PHP基础知识点

PHP的中文字符串截取

2016-12-06  本文已影响817人  睡着的咖啡豆zZ

在PHP中,substr()函数截取带有中文字符串的话,可能会出现乱码,这是因为中西文一个字节所占有的字节数不一样,而substr()的长度参数是按照字节去算的。substr()截取位数不准确,substr()硬生生地将一个中文字符“锯”成两半,造成断开的字符会把其后的码位拉过来一起做一个字,所以出现了PHP substr()截取中文乱码现象。

在GB2312编码时,一个中文占2个字节,英文为1个字节,而在UTF-8编码当中,一个中文可能占有2个或3个字节,英文或半角标点占1字节。

0. 原生解决方案

PHP中有原生的解决方案,mb_substr()方法。需要开启mbstring扩展,方法:
在php的配置文件中,寻找到extension=php_mbstring.dll,确保扩展被加载——此行首无分号。

下面重点讲使用基本函数substr去实现中文字符串的截取。

1. 基于substr()解决方案

1.1解决思路:

UTF-8编码的字符可能由1-3个字节组成,具体数目可以由第一个字节判断出来。
第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符,否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号)。

1.2 substr()语法

substr()中文文档
string substr ( string $string , int $start [, int $length ] )

参数

string

输入字符串。必须至少有一个字符。

start

如果 start 是非负数,返回的字符串将从 stringstart 位置开始,从 0 开始计算。
如果 start 是负数,返回的字符串将从 string 结尾处向前数第 start 个字符开始。
如果 string 的长度小于 start ,将返回 FALSE

length

如果提供了正数的 length,返回的字符串将从 start 处开始最多包括 length 个字符(取决于 string 的长度)。
如果提供了负数的 length ,那么 string 末尾处的 length 个字符将会被省略(若 start 是负数则从字符串尾部算起)。
如果 start 不在这段文本中,那么将返回 FALSE
如果提供了值为 0FALSENULLlength,那么将返回一个空字符串。
如果没有提供 length,返回的子字符串将从 start 位置开始直到字符串结尾。

返回值

返回提取的子字符串, 或者在失败时返回 **FALSE
**。

1.3 myGBsubstr()

 function myGBsubstr($string, $start, $length) {
    if (strlen($string) > $length) {
        $str = null;
        $len = 0;
        $i = $start;
        while ( $len < $length) {
        if (ord(substr($string, $i, 1)) > 0xc0) {
            $str .=substr($string, $i, 3);
            $i+= 3;
        }elseif (ord(substr($string, $i, 1)) > 0xa0) {
            $str .= substr($string, $i, 2);
            $i+= 2;
        }else {
            $str.=substr($string, $i, 1);
            $i++;
        }
        $len ++;
        }
        return $str;
    }else {
        return $string;
    }
}

1.4 优化

判断mbstring模块是否可用,如果可用使用原生的mb_substr()函数,反之,使用自己定义的中文字符串截取函数。

function GBsubstr($string, $start,$length) {
    if (!function_exists(mb_substr)) {
        myGBsubstr($string, $start, $length);
    } else {
        mb_substr($string, $start, $length, 'utf8');
    }
}
上一篇下一篇

猜你喜欢

热点阅读