识别gbk编码和utf8编码的方法,php版

PHP 林涛 5090℃ 0评论

编码自动识别的基本思想如下:

   1.看给定的字节串是否符合utf8编码规则。如果不符合则为gbk编码。

   2.如果给定的字节串中没有符合utf8三字节规则的,则为gbk编码。中文在utf8中占三个字节。

   3.如果给定的字节串能对应上gbk编码中的中文,且无法对应上utf8编码中的中文,则为gbk编码。

   4.特殊情况,特殊处理。如 “鏈條” 和 “瑷媄”。

   总体思想是,先默认为utf8编码,再根据一些非utf8编码的情况逐步筛选。

   准确率和效率还是不错的。20万多条query,1秒钟就可以处理完。

   php代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function detect_encoding($str){
    $len strlen($str);
    $encoding "utf8";
    $is_utf8_chinese = false;
    for ($i = 0; $i $len$i++) {
        if ( (ord($str[$i]) >> 7) > 0 ) { //非ascii字符
            if (ord($str[$i]) <= 191 ) {
                $encoding "gbk0";
                break;
            else if ( ord($str[$i]) <= 223 ) { //前两位为11
                if empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 ) { //紧跟后两位为10
                    $encoding "gbk1";
                    break;
                else {
                    $i += 1;
                }
            else if ( ord($str[$i]) <= 239 ) { //前三位为111
                if empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2) { //紧跟后两位为10
                    $encoding "gbk2";
                    break;
                else {
                    $i += 2;
                    $is_utf8_chinese = true;
                }
            else if ( ord($str[$i]) <= 247 ) { //前四位为1111
                if empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 orempty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2) { //紧跟后两位为10
                    $encoding "gbk3";
                    break;
                else {
                    $i += 3;
                }
            else if ( ord($str[$i]) <= 251 ) { //前五位为11111
                if empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 orempty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 orempty($str[$i+4]) or  ord($str[$i+4]) >> 6 != 2) { //紧跟后两位为10
                    $encoding "gbk4";
                    break;
                else {
                    $i += 4;
                }
            else if ( ord($str[$i]) <= 253 ) { //前六位为111111
                if empty($str[$i+1]) or  ord($str[$i+1]) >> 6 != 2 or empty($str[$i+2]) or  ord($str[$i+2]) >> 6 != 2 orempty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 orempty($str[$i+4]) or  ord($str[$i+4]) >> 6 != 2 orempty($str[$i+5]) or  ord($str[$i+5]) >> 6 != 2 ) { //紧跟后两位为10
                    $encoding "gbk5";
                    break;
                else {
                    $i += 5;
                }
            else {
                $encoding "gbk6";
                break;
            }
        }
    }
  
    if ($is_utf8_chinese == false){
        $encoding "gbk10";
    }
    if ($encoding == "utf8" && preg_match("/^[".chr(0xa1)."-".chr(0xff)."\x20-\x7f]+$/"$str) && !preg_match("/^[\x{4e00}-\x{9fa5}\x20-\x7f]+$/u"$str)) {
        $encoding "gbk7";
    }
    //echo $encoding;
    if ($encoding == "utf8") {
        //echo "utf8";
        return ($str == "鏈條" || $str == "瑷媄")? $str: mb_convert_encoding($str"gbk""utf8");
    else {
        //echo "gbk";
        return $str;
    }
}

   记得代码最好在gbk编码中运行,因为代码中有汉字($str == “鏈條” || $str == “瑷媄”)比较。当然你可以在utf8编码中运行,只要把汉字处理下

 

原文连接:http://blogread.cn/it/article/7107?f=hot1

如需转载请注明: 转载自26点的博客

本文链接地址: 识别gbk编码和utf8编码的方法,php版

转载请注明:26点的博客 » 识别gbk编码和utf8编码的方法,php版

喜欢 (0)
发表我的评论
取消评论

表情