博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gbk和utf8编码自动识别方法[php版]
阅读量:7088 次
发布时间:2019-06-28

本文共 3222 字,大约阅读时间需要 10 分钟。

目前中文网页主流的编码为gbk和utf8两种编码。因此,我们做编码识别的前提是,编码不是gbk就是utf8.

编码自动识别的基本思想如下:
1.看给定的字节串是否符合utf8编码规则。如果不符合则为gbk编码。具体utf8编码规则件日志《》。
2.如果给定的字节串中没有符合utf8三字节规则的,则为gbk编码。中文在utf8中占三个字节。
3.如果给定的字节串能对应上gbk编码中的中文,且无法对应上utf8编码中的中文,则为gbk编码。
4.特殊情况,特殊处理。如 “鏈條” 和 “瑷媄”。
总体思想是,先默认为utf8编码,再根据一些非utf8编码的情况逐步筛选。

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

php代码如下:

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 or empty($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 or empty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 or empty($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 or empty($str[$i+3]) or  ord($str[$i+3]) >> 6 != 2 or empty($str[$i+4]) or  ord($str[$i+4]) >> 6 != 2 or empty($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://olbql.baihongyu.com/

你可能感兴趣的文章
【修真院“善良”系列之十六】代码结构中Dao,Service,Controller,Util,Model是什么意思,为什么划分...
查看>>
js数据结构-栈
查看>>
前端构建_webpack
查看>>
Looper源码
查看>>
微信小程序开发系列五:微信小程序中如何响应用户输入事件
查看>>
程序员如何优雅的记录笔记(同步云端,图床,多端发布)
查看>>
极速高清——给你带来全新的高清视野
查看>>
数据结构之链表【上】
查看>>
Go并发实战笔记整理
查看>>
奇葩问题
查看>>
使用 Laravel 5.5+ 更好的来实现 404 响应
查看>>
PHP 网络编程小白系列 —— Accept 阻塞模型
查看>>
流畅的python读书笔记-第十六章-携(协)程
查看>>
Python学到什么程度才可以去找工作?掌握这4点足够了!
查看>>
用状态机写轮播
查看>>
【379天】每日项目总结系列116(2018.02.19)
查看>>
人工智能在搜索中的应用
查看>>
Vue2从0到1(一):用webpack打包vue
查看>>
【Vue样式绑定】
查看>>
leetcode75. Sort Colors
查看>>