作者:刘春龙(http://www.longbill.cn/)
本文地址:http://www.longbill.cn/blog/mysql_fulltext/
比如我们有一句话:你好我是刘春龙 那么我们可以这样来分词: 你好 好我 我是 是刘 刘春 春龙
这样虽然看起来有点傻,但是实际应用起来确实可行,因为我们搜索时候输入的关键词也是按照这个方法分词。 下面有个我自己写的函数,可以实现这种分词。传入三个参数,分别是:
1.需要分词的字符串,必须,英文,标点,数字,汉字,日语等都可以。编码为UTF-8
2.是否返回字符串,可选,默认是。如果传入false,那么将返回一个数组。
3.是否base64_encode中文,可选,默认是。Mysql的全文搜索有个配置是 ft_min_word_len 这个值一般是
4,而我们分成的中文词语是两个字,就不会被mysql认为是一个词。而base64_encode过后,词语的长度为8,就不存在最小长度问题了。 base64_encode过后数据量会增大 50%。
注意,这里输入和输出的字符串编码都是UTF-8
function string2words($s,$return_string = true,$encode64 = true)
{
$re = '';
//匹配汉字
if (preg_match_all("/([x{4e00}-x{9fff}]{2,})/u",$s,$ms))
{
foreach($ms[0] as $w)
{
//关键部分:分词
$l = strlen($w)/3;
for($i=0;$i<$l;$i++)
{
$wi = substr($w,$i*3,6);
if (strlen($wi) > 3)
{
$re .= ($encode64)?' '.str_replace(',','@',base64_encode($wi)):' '.$wi;
}
}
}
}
//匹配数字
if (preg_match_all("/(d+[.]?d+)/",$s,$ms))
{
foreach($ms[0] as $wi)
{
if(strlen($wi) >= 2)
{
$re .= ($encode64)?' '.str_replace(',','@',base64_encode($wi)):' '.$wi;
}
}
$s = preg_replace("/(d+[.]?d+)/",' ',$s);
}
//去掉所有双字节字符
$s = preg_replace("/([^x{00}-x{ff}]+)/u",' ',$s);
$re = $s.' '.$re;
if (!$return_string)
{
$re = preg_replace("/([^d])([,.-?n])([^d])/",'$1 $3',$re);
$re = trim(preg_replace("/[s]{2,}/",' ',$re));
$arr = explode(' ',$re);
$re = array();
foreach($arr as $a)
{
if (strlen($a) >= 2) $re[] = $a;
}
return $re;
}
else
{
$re = trim(preg_replace("/[s,.]{2,}/",' ',$re));
return $re;
}
}
另附一个中文分析系统:
http://www.hightman.cn/index.php?scws