[转]PHP中文二元分词技术函数(UTF-8编码)

因mysql不直接支持对中文的全文检索,基于mysql的数据库的搜索功能设计一向都成为了难题。
当然想偷懒,完全可以用like来对付,但你的网站的数据量到了几百万的时候……使用KingCMS建站的站长,要么就休了搜索功能,要么就考虑转向其他CMS类系统。
参考了网上的代码,但基本都是对GBK码的编码,在UTF-8下会出错,所以在UTF-8下重写了分词函数,如下:

/**
* 中文分词函数,输出数字组合
*/
function wordSegment(str) {search = array(":",")","(",".","。",",","!",";","“","”","‘","’","[","]","、","—"," ","《","》","-","…","【","】");
   str=str_replace(search,' ',str);
   //英文单词3个以上,中文2词
   preg_match_all ('#([A-Za-z0-9]{3,}|([\xC0-\xFF][\x80-\xBF]+)+)#',str,array,PREG_PATTERN_ORDER);ss=array();
   if (!empty(array[1])) {
    foreach (array[1] as val) {
     //英文单词
     if (preg_match('/\w+/',val)) {
      ss[]=val;
     }else{//中文字符
      preg_match_all('#[\xC0-\xFF][\x80-\xBF]+#',val,out,PREG_PATTERN_ORDER);
      if (!empty(out[0])) {count=count(out[0]);
       for (i = 0 ; $i < $count-1 ; $i++) {
        $t=$out[0][$i].$out[0][$i+1];
        $t=kc_iconv($t,'GBK','UTF-8');
        $ss[]=sprintf("%02d%02d%02d%02d",ord($t{0})-160,ord($t{1})-160,ord($t{2})-160,ord($t{3})-160);
       }
      }
     }
    }
   }
     return empty($ss) ? '' : implode(' ',array_unique($ss));
}

/**
* 编码转换
* @param string $s   录入的
* @param string $out 输出编码类型
* @param string $in 输入编码类型
* @return string
*/
function kc_iconv($s,$out='UTF-8',$in='GBK'){
if($out==$in)
   return $s;
if(function_exists('iconv')){
   $s=iconv($in,"$out//IGNORE",$s);
}elseif(function_exists('mb_convert_encoding')){
   $s=mb_convert_encoding($s,$out,$in);
}
return $s;
}

考虑到UTF-8编码转换为区位码后占去6个字符,所以做了iconv转换,这样可以减少两位字符,尽可能的减少索引文件的大小。
来源:http://hi.baidu.com/sincs/blog/item/5b9546dab3452dd0b6fd488e.html

发表评论