突出搜索中的多个关键字

时间:2010-05-03 11:02:49

标签: php html search arrays highlight

我正在使用此代码突出显示搜索关键字:

function highlightWords($string, $word)
 {

        $string = str_replace($word, "<span class='highlight'>".$word."</span>", $string);
    /*** return the highlighted string ***/
    return $string;

 }

 ....

  $cQuote =  highlightWords(htmlspecialchars($row['cQuotes']), $search_result);

但是,这只突出显示一个关键字。如果用户输入多个关键字,则会缩小搜索范围,但不会突出显示任何字词。我怎么能突出一个以上的单词?

8 个答案:

答案 0 :(得分:25)

正则表达式是要走的路!

function highlight($text, $words) {
    preg_match_all('~\w+~', $words, $m);
    if(!$m)
        return $text;
    $re = '~\\b(' . implode('|', $m[0]) . ')\\b~';
    return preg_replace($re, '<b>$0</b>', $text);
}

$text = '
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
';

$words = 'ipsum labore';

print highlight($text, $words);

要以不区分大小写的方式匹配,请将“i”添加到正则表达式

    $re = '~\\b(' . implode('|', $m[0]) . ')\\b~i';

注意:对于像“ä”这样的非英语字母,结果可能因地区而异。

答案 1 :(得分:17)

PHP&gt; 5.3.0,尝试preg_filter()

/**
 * Highlighting matching string
 * @param   string  $text           subject
 * @param   string  $words          search string
 * @return  string  highlighted text
 */
public function highlight($text, $words) {
    $highlighted = preg_filter('/' . preg_quote($words, '/') . '/i', '<b><span class="search-highlight">$0</span></b>', $text);
    if (!empty($highlighted)) {
        $text = $highlighted;
    }
    return $text;
}

答案 2 :(得分:5)

假设单词是以空格分隔的字符串形式输入的,您可以使用explode

$words = explode(' ', $term);

虽然如果你想确保没有多个空格,你可能想先从字符串中删除它们

$term = preg_replace('/\s+/', ' ', trim($term));
$words = explode(' ', $term);

然后你必须生成替换数组

$highlighted = array();
foreach ( $words as $word ){
    $highlighted[] = "<span class='highlight'>".$word."</span>"
}

然后

str_replace($words, $highlighted, $string);

所以把它放在一起

function highlightWords($string, $term){
    $term = preg_replace('/\s+/', ' ', trim($term));
    $words = explode(' ', $term);

    $highlighted = array();
    foreach ( $words as $word ){
        $highlighted[] = "<span class='highlight'>".$word."</span>"
    }

    return str_replace($words, $highlighted, $string);
}

答案 3 :(得分:4)

这里是一个简单的功能,只突出显示匹配文字。

function highlighter_text($text, $words)
{
    $split_words = explode( " " , $words );
    foreach($split_words as $word)
    {
        $color = "#e5e5e5";
        $text = preg_replace("|($word)|Ui" ,
            "<span style=\"background:".$color.";\"><b>$1</b></span>" , $text );
    }
    return $text;
}

通话功能

答案 4 :(得分:4)

在搜索中突出显示多个关键字,包括变音符号

我使用过之前编写的正则表达式,并将\w替换为[A-Za-z0-9_äöüÄÖÜ]。如你所见,我添加了变音符号äöüÄÖÜ。 我也删除了\b,因此它会匹配搜索字词的任何外观。

实施例

搜索字词
Su shamp

文字:
阳光闪亮的洗发水

<强>结果:
Su n闪亮 shamp oo

我使用的代码:

private function getSearchTermToBold($text, $words)
{
    preg_match_all('~[A-Za-z0-9_äöüÄÖÜ]+~', $words, $m);
    if (!$m)
        return $text;
    $re = '~(' . implode('|', $m[0]) . ')~i';
    return preg_replace($re, '<b>$0</b>', $text);
}

答案 5 :(得分:1)

根据user187291的建议,只需更改以下代码,即可以黄色背景突出显示文字。

 return preg_replace($re, '<SPAN style="BACKGROUND-COLOR: #ffff00"><b>$0</b></SPAN>', $text); 

答案 6 :(得分:0)

将您的搜索查询拆分为单词,然后分别突出显示每个单词。

虽然可以更好地在javascript中执行突出显示。 jQuery的“包含”选择器可能有助于避免在你去的时候替换标记元素的问题...

http://api.jquery.com/contains-selector/

答案 7 :(得分:0)

其他解决方案在查找突出显示术语时可能不区分大小写,但不保留其原始字符串的大小写。因此,搜索“st”将找到“ST”,但将其突出显示为搜索词“st”。

我使用以下内容。它首先形成replace数组,然后使用str_replace()和数组参数 - 这避免了递归。

function highlightStr($haystack, $needle, $highlightStyle) {

    if (strlen($highlightStyle) < 1 || strlen($haystack) < 1 || strlen($needle) < 1) {
       return $haystack;
    }

    preg_match_all("/$needle+/i", $haystack, $matches);

    $matches[0] = array_unique($matches[0]);

    if (is_array($matches[0]) && count($matches[0]) >= 1) {
        foreach ($matches[0] as $ii=>$match)
            $replace[$ii]="<span style='$highlightStyle'>$match</span>";

        $haystack = str_replace($matches[0], $replace, $haystack);
    }

    return $haystack;
}