php mysql搜索,突出显示包含提供的关键字的结果部分

时间:2014-03-09 10:46:47

标签: php mysql search-engine

出于测试目的,我存储了以下颜色的数据库名称:

Apple green
Banana yellow
Brick red
Charcoal
Coffee

我使用$_GET和地址栏创建了搜索和显示结果的功能,到目前为止,它们完美无缺。例如,如果我在搜索表单中键入:ap le ee

我的地址栏如下所示:

http://test.com/file.php?keywords=ap+le+ee

我的结果显然是Apple green

如果我输入此内容:c oco

我的结果是:CharcoalCoffee

此时我想升级此搜索引擎并在结果中仅突出显示与提供的关键字匹配的那些部分,因此我想要达到的目的是:

如果我输入:app ee

我希望得到这样的结果:<strong>App</strong>le gr<strong>ee</strong>n

我不知道如何实现它。

我将结果称为:

$colors = get_colors(isset($_GET['keywords']) ? $_GET['keywords'] : null);
foreach($colors as $color) {
    echo $color['color_name'] . '<br />';
}

如果有人能帮我这么做,我将非常感激,提前谢谢你:)

---编辑--- 10.03.2014 08:34

现在使用的代码是:

$colors = get_colors(isset($_GET['keywords']) ? $_GET['keywords'] : null);
foreach($colors as $color) {
    $output = $color['color_name'];

    foreach (explode(' ', $_GET['keywords']) as $term)
        $output = preg_replace('/(?![^<>]*>)'.preg_quote($term,"/").'/i', '<span style="color:red;">$0</span>', $output);

    echo $output . "<br />";
}

完美无缺的事情(测试用例Banana yellowCharcoal):

  1. 无论我输入l o还是o l都无关紧要,这些都会在测试案例中正确突出显示。

  2. 如果我输入最后一个字母,
  3. 脚本不会失败,我可以输入ban w,它会正确返回突出显示的Banana yellow

  4. 唯一不起作用的是:

    1. 如果我输入bana nana,则只会在bana
    2. 中突出显示Banana yellow

      所以我相信现在我正在寻找重叠术语的解决方案,如果我键入bri ick,它应该突出显示Brick中的所有Brick red而不是Bri }。

      有想法如何排序的人?

2 个答案:

答案 0 :(得分:3)

从外观上看,您允许多个搜索字词,以空格分隔。所以我会循环使用这些术语并在输出之前对颜色进行替换。

foreach($colors as $color) {
    $output = $color['color_name'];
    foreach(explode(' ', $_GET['keywords']) as $term)
        $output = preg_replace('/'.$term.'(?![^>]*>)/i', '<strong>'.$term.'</strong>', $output);
    echo  preg_replace('/And\b/', 'and', ucwords($output)).'<br />';
}

答案 1 :(得分:1)

使用@Utkanos建议:

foreach($colors as $color) {
    $output = $color['color_name'];
    foreach(explode(' ', $_GET['keywords']) as $term)
        $output = preg_replace('/('.$term.')(?![^>]*>)/i', '<strong>$1</strong>', $output);
    echo  $output .'<br />';
}

您希望preg_match的结果替换$term

对不起,这是一个明显“简单”问题的代码很多,但这应该做到,你期望的是什么:

$colors = array("Apple green",
                "Banana yellow",
                "Brick red",
                "Charcoal",
                "Coffee",
                "Fire red");

$terms = "re e";
$output = "";

foreach($colors as $color) {
    $output = $color;
    $words = array();

    foreach(explode(' ', $terms) as $term) {
        $match = preg_match_all("/(". $term .")/i", $output, $hits, PREG_OFFSET_CAPTURE);

        if($match) {
            $positions = array();
            foreach($hits[1] as $hit) {

                for($i = $hit[1]; $i < strlen($hit[0]) + $hit[1]; $i++) {
                    $positions[] = $i;
                }
                $words[] = array($hits[0][0][0], $positions);

            }
        }
    }

    $positions = array();
    foreach($words as $word) {
        foreach($word[1] as $position)
            $positions[] = $position;
    }

    $positions = array_unique($positions);
    asort($positions);
    $positions = array_values($positions);

    if(count($positions) > 0) {
        $offset = 0;
        $open = false;
        $closed = true;

        $i = $positions[0];
        foreach($positions as $value) {

            if($value != $i AND !$closed) {
                $output = substr_replace($output, "</strong>", $i + $offset, 0);
                $offset += 9;
                $open = false;
                $closed = true;
                $i = $value;
            }

            if(!$open AND $closed) {
                $output = substr_replace($output, "<strong>", $value + $offset, 0);
                $offset += 8;
                $open = true;
                $closed = false;
            }

            $i++;

        }

        if(!$closed)
            $output = substr_replace($output, "</strong>", $positions[count($positions)-1] + $offset +1, 0);
    }


    echo $output ."<br/>";

}