gbk和utf8编码自动识别方法[php版]
浏览:2738次 出处信息
目前中文网页主流的编码为gbk和utf8两种编码。因此,我们做编码识别的前提是,编码不是gbk就是utf8.
编码自动识别的基本思想如下:
1.看给定的字节串是否符合utf8编码规则。如果不符合则为gbk编码。
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编码中运行,只要把汉字处理下。
建议继续学习:
- 字符编码和中文乱码小叙 (阅读:6532)
- 中文编码杂谈 (阅读:5771)
- Hadoop的map/reduce作业输入非UTF-8编码数据的处理原理 (阅读:5227)
- PHP编码规范 (阅读:5121)
- base64_encode 和 urlencode (阅读:4732)
- Linux screen窗口中文乱码问题 (阅读:4805)
- UTF-8编码中BOM的检测与删除 (阅读:4754)
- Unicode与字符汉字相互转换 (阅读:4724)
- python-django的中文编码总结 (阅读:4565)
- JAVASCRIPT完美实现UTF8页面提交数据到GB2312 (阅读:4396)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
后一篇:PHP语法分析器:RE2C && BISON 总结 >>
文章信息
- 作者:沧龙 来源: 搜索技术博客-淘宝
- 标签: gbk utf8 编码
- 发布时间:2014-12-01 23:37:27
建议继续学习
近3天十大热文
-
[928] WordPress插件开发 -- 在插件使用 -
[134] 解决 nginx 反向代理网页首尾出现神秘字 -
[53] 整理了一份招PHP高级工程师的面试题 -
[52] 如何保证一个程序在单台服务器上只有唯一实例( -
[51] 海量小文件存储 -
[51] 用 Jquery 模拟 select -
[50] 全站换域名时利用nginx和javascri -
[50] Innodb分表太多或者表分区太多,会导致内 -
[49] CloudSMS:免费匿名的云短信 -
[47] jQuery性能优化指南
