如何自动的检测字符串编码

如何自动的检测字符串编码

很多时候,一个字符串,你很难检测它的编码。是理论上就不行,比如一个字符串,你把他当作一个utf8的编码是一个汉字串,把他当成gb2312 还是一个汉字出串,而且在字库里面都存在。所以,我们检查也只能是说,大部分能检测出来。

    我遇到的问题是这样的,百度搜索引擎的中关键字的问题。http://www.baidu.com/s?tn=159sifu_pg&wd=%E8%83%8E%E6%95%99%E9%9F%B3%E4%B9%90%E6%AC%A3%E8%B5%8F  在大多数情况下,百度默认编码是gb2312的,如果是utf8会加一个ie字段。但是比如在好hao123里面搜索的,或者其他地方搜索然后进入百度的,可能默认编码是不一样的。比如上面这搜索如果直接输入浏览器,百度自身也是不能解析的,是乱码。

    既然默认编码是gb2312,而且我统计了一下,90%的情况下都是gb2312,所以,我的检测函数不能出现本来是gb2312的,结果被检测出utf8. 基本思路是:

    1. 把所有的ascii去掉,如果全部都是ascii,那么就是gb2312。

    2. 假设这个字符串是gb2312,用一个正则检查它是否是真的gb2312,如果不是,那么就是utf-8

    3. 然后,用iconv 把字符串转换成utf8,如果转换不成功,那么原来可能不是真正的一个gb2312编码的字符

     (用正则匹配我已经尽量精确,但是,gb2312的编码不是连续的,还是会有空洞),那么最后的编码就是utf-8.

    4. 否则就是gb2312 编码

 加入这样的检查功能后,在1000个关键字里面,就出现了1个乱码,比以前的近100个关键字乱码少了很多。

我的这个gb2312 正则判断的不是汉字,而是编码的所有范围了。汉字的范围要小一点。查询详细的gb2312 编码组成情况,可以看我前面的一篇提取关键字的文章,源代码里面有对

gb2312的详细分类。发布一个纯PHP的中文关键字自动提取工具

5. 如果你要更加精确的进行判断,那么还可以进行分词。因为一个字符串,虽然在gb2312下面是汉字,在utf8上也是汉字,但是,在gb2312上构成一个词汇,在utf8上构成一个词汇的概率很小,所以,这样,可以判断分词后一共多少个词,如果用某种编码分词,不能构成词,那么就可以排除这样的情况。但是,大多数情况下没有必要这样精确。

下面是源代码:ExpandedBlockStart.gif代码

function  utf8_gb2312( $str ,   $default   =   ' gb2312 ' )
{
    
$str   =   preg_replace ( " /[\x01-\x7F]+/ " ,   "" ,   $str );
    
if  ( empty ( $str ))  return   $default ;
    
    
$preg   =    array (
        
" gb2312 "   =>   " /^([\xA1-\xF7][\xA0-\xFE])+$/ " ,   // 正则判断是否是gb2312
         " utf-8 "   =>   " /^[\x{4E00}-\x{9FA5}]+$/u " ,        // 正则判断是否是汉字(utf8编码的条件了),这个范围实际上已经包含了繁体中文字了
    );

    
if  ( $default   ==   ' gb2312 ' ) {
        
$option   =   ' utf-8 ' ;
    } 
else  {
        
$option   =   ' gb2312 ' ;
    }

    
if  ( ! preg_match ( $preg [ $default ] ,   $str )) {
        
return   $option ;
    }
    
$str   =  @ iconv ( $default ,   $option ,   $str );
    
    
// 不能转成 $option, 说明原来的不是 $default
     if  ( empty ( $str )) {
        
return   $option ;
    }
     return   $default ;
}

 

 

posted @ 2010-12-20 18:46 暮夏 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值