PHP截取UTF8字符串 utf-8 可以能占一个字符 二个字符 或者三个字符

转载 2013年12月03日 13:31:52

PHP截取UTF8字符串  


想必很多人从一开始接触编程到现在,都有一个惯性思维:英文字符占用一个字节,中文字符占用两个字节。不错,英文字符是占用一个字节,但中文字符占用两个字节是相对于GBK编码而言(当然,其他一些编码如GB2312也是),但是在时下国际流行的UTF8编码中,一个中文字符占用3个字节。不要惊讶,这是一个事实,而且应该成为一个常识。
UTF8编码可能出现一个字符占用1个、2个、3个甚至更多字节的情况,如英文字符abc占用一个字节,中文字符占用三个字节,那么什么字符占用两个字节呢?这个问题我一开始并没有发现,只是前几天有人留言,首页的评论截取竟然出现了乱码的情况:

2011年09月21日 - bzyyc.happy - 点烟看寂寞燃烧
最开始并没有发现这两个乱码出现的问题在哪里,后来仔细验证了下,发现是处在·这个字符上(键盘左上角,中文输入法下),它占用两个字节。而emlog的截取字符串函数,除了英文字符外,默认其他的都占三个字节了,因此导致乱码出现。
查阅了相关资料,得出了一个结论:UTF8编码的字符中,第一个字节ASCII值大于等于224的,其与之后的2个字节一起组成一个UTF8字符,第一个字节ASCII值大于192等于小于224的,其与之后的1个字节组成一个UTF-8字符,第一个字节ASCII值小于192的,其本身成为一个UTF8字符。于是在PHP中将·字符的ASCII打印出来,第一个字节是194,第二个字节是183,木有第三个字节了,于是截取的字符中,若包含·字符,就会出现乱码了。
问题找到,解决方案也就很简单了,分别判断处理下就OK。写了如下函数用于截取:


function subString($str, $start, $length) {
    $i = 0;
    //完整排除之前的UTF8字符
    while($i < $start) {
        $ord = ord($str{$i});
        if($ord < 192) {
            $i++;
        } elseif($ord <224) {
            $i += 2;
        } else {
            $i += 3;
        }
    }
    //开始截取
    $result = '';
    while($i < $start + $length && $i < strlen($str)) {
        $ord = ord($str{$i});
        if($ord < 192) {
            $result .= $str{$i};
            $i++;
        } elseif($ord <224) {
            $result .= $str{$i}.$str{$i+1};
            $i += 2;
        } else {
            $result .= $str{$i}.$str{$i+1}.$str{$i+2};
            $i += 3;
        }
    }
    if($i < strlen($str)) {
        $result .= '...';
    }
    return $result;
}

相关文章推荐

PHP中不同编码的汉字占的字节数不同gbk,GBK,UTF-8,utf-8

问题: 对于gb2312,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在UTF-8编码下,一个汉字占3个字节)这句话准确吗?utf-8的中文一定占...

PHP截取中文字符串方法总结

程序一:PHP截取中文字符串方法 由于网站首页以及vTigerCRM里经常在截取中文字符串时出现乱码(使用substr),今天找到一个比较好的截取中文字符串方法,在此与大家共享。 function...

php中中文字符串的截取和获取长度 mb_substr() mb_strlen()

php中 mb_substr($str,$start,$len,$encoding)用于中文字符串的截取,在相应的编码页面输入相应的$encoding mb_strlen($str,$encodd...
  • kbx8916
  • kbx8916
  • 2016年09月15日 23:12
  • 1029

解析UTF8字符串,并截取每个字符到vector(C++代码)

C++小函数,从给定string中,解析编码并获取每一个字符 例如 string=“游历德国:萨尔河畔-德国Saarbrucken 风景壁纸” 解析后的vector,每个字符被解析...

php开发之截取中文字符,包括utf-8

程序一:PHP截取中文字符串方法 今天找到一个比较好的截取中文字符串方法,在此与大家共享。 function msubstr($str, $start, $len) { $tmpstr ...

[C/C++]_[初级]_[替换过滤utf8字符串里无效字符]

场景: 1. 分析数据时,获取到的数据是字符串,但是有可能不是正确的完整的utf8字符串,打印出来或输出到文件时表现出来的就是显示乱码. 这时候就需要过滤掉非法字符使utf8字符串能正确显示, 比如把...

如何去除utf-8字符串里头的非法字符

在开发的过程中碰到了在utf-8的字符串里头有非法字符的问题,搜了下,有不少人遇到了相同的问题。 有iconv.open("UTF-8", UTF-8//IGNORE") Table 3-7. W...

怎么把存储UTF-8编码的字符串转换成实际字符

踩过的坑1:怎么把存储UTF-8编码的字符串转换成实际字符首先说明下问题。之前用爬虫从网上down数据的时候因为没有思考到位,结果出现了一个很奇葩的问题。一般来说中文采用UTF8编码后写成byte[]...

PHP字符编码(UTF-8/GBK)与json_encode/json_decode的关系

在项目中,因为字符编码的问题,踩了不少坑,之前踩,现在还接着踩,现在把它们总结出来,只希望以后不要再踩这坑了,我把我踩过的坑总结一下:   1)将数组转成json数据,json数据为null或为空字...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:PHP截取UTF8字符串 utf-8 可以能占一个字符 二个字符 或者三个字符
举报原因:
原因补充:

(最多只允许输入30个字)