关键词高亮算法

jerry thinkphp 2015年11月19日 收藏
在搜索系统中,经常会有高亮搜索关键词的需要,而在关键词不止一个且容易重叠的时候,普通的关键词高亮算法就容易出错了。所以这里介绍一下我自己想到的算法。如果有问题可以给我发邮件~ Email:me@filowlee.com
    /**
     * 设置关键词高亮的字符串处理函数
     * @param [string] $str      [要高亮的字符串]
     * @param array  $word_arr [关键词]
     */
    public function setKeyWords($str,$word_arr=array()){
        // 设置多字节字符内部编码为utf8
        mb_internal_encoding("UTF-8");
        // 创建一个跟字符串长度一致的数组,用0填充
        $map=array_fill(0,mb_strlen($str),0);
        // 遍历关键词数组,将关键词对应的map数组的位置上的数字置为1
        foreach ($word_arr as $value) {
            $pos=-1;
            $pos_count=0;
            $pos_arr=array();
            // 如果找到了这个关键词,就将这个词的位置存入位置数组中(来支持多次出现此关键词的情况)
            while(($pos=mb_strpos($str,$value,$pos+1))!==false && $pos_count<5){
                $pos_arr[]=$pos;
                $pos_count++;
            }
            // 遍历数组,将对应位置置1
            foreach ($pos_arr as $pos_val) {
                if($pos_val!==false){
                    $fill=array_fill($pos_val,mb_strlen($value),1);
                    $map = array_replace($map,$fill);
                }
            }
            $pos=null;
        }

        // 遍历map数组,加入高亮代码
        $flag=0;
        $position=-1;
        $result="";  // 结果数组
        foreach ($map as $key => $value) {
            if($value==1){
                // 如果第一次出现1,则加上html标签头
                if($flag==0) $result.="<span class=\"keyword\">";
                $flag=1;
            }else{
                // 如果已经到了一个0,但上一个还是1时,加入html标签尾
                if($flag==1){
                    $position=$key-1;
                    $flag=0;
                    $result.="</span>";
                }
            }
            // 将该位置的字符加入结果字符串中
            $result.=mb_substr($str,$key,1);
        }
        return $result;
    }
附上一个简单的关键词分离代码;
    $query_words=explode(" ",trim($str));
    foreach ($query_words as $key => $value) {
        if(!$value) unset($query_words[$key]);
    }