编码自动识别的基本思想如下:
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 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://blogread.cn/it/article/7107?f=hot1
如需转载请注明: 转载自26点的博客
本文链接地址: 识别gbk编码和utf8编码的方法,php版
转载请注明:26点的博客 » 识别gbk编码和utf8编码的方法,php版