在搜索中突出显示多个关键字

Posted

技术标签:

【中文标题】在搜索中突出显示多个关键字【英文标题】:highlight multiple keywords in search 【发布时间】:2011-02-14 23:59:03 【问题描述】:

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

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);

但是,这只会突出显示一个关键字。如果用户输入了多个关键字,它将缩小搜索范围,但不会突出显示任何单词。如何突出显示多个单词?

【问题讨论】:

我切换到 javascript 来突出显示搜索。问题是,在属性中搜索到的值(或搜索,例如&lt;div)会在没有仔细工作的情况下破坏标记。在 JS 中,它是一个 20-liner 保证没有副作用。 【参考方案1】:

php > 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;

【讨论】:

我比其他人尝试得更好,:D 这个比公认的答案好,代码很短,效果很好。 太棒了!您将如何允许搜索像这样的两个字母:eé?如何指定使用 UTF-8,以便两个字母都被高亮显示? 尝试在preg_*前加mb_internal_encoding('UTF-8');,并加u修饰符:preg_filter('/' . preg_quote($words) . '/iu', ... 这个答案比公认的真实答案要好,现在仍然像魅力一样工作【参考方案2】:

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

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

示例

搜索词: 苏洗发水

文字: 防晒洗发水

结果:n闪亮shampoo


我用过的代码:

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);

【讨论】:

【参考方案3】:

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

我使用以下内容。它首先形成替换数组,然后使用带有数组参数的 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;

【讨论】:

【参考方案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;

调用函数

【讨论】:

【参考方案5】:

根据用户 187291 的建议,只需更改以下代码即可使文本以黄色背景突出显示。

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

【讨论】:

【参考方案6】:

正则表达式是要走的路!

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';

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

【讨论】:

如何使它不区分大小写?如果用户输入'good',它只会显示'good'而不是'Good'。 谢谢。最后一个问题:如果用户输入'good',它将显示所有突出显示关键字'good'的结果。但是,它不会突出显示“goodness”一词中的“good”,尽管它会显示在结果中。 @user187291 如何调整它以使用非英语字符并突出显示 1 个字符的关键字? 但是你怎么能同时突出ma这两个词呢?你如何让它成为 utf-8 独立的? 对于那些想知道波浪字符 ~ 的人。它只是用作表达式的分隔符,而不是正斜杠 /.【参考方案7】:

假设单词是以空格分隔的字符串输入的,您可以使用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);

【讨论】:

对我来说完美的解决方案..稍微改变一下..非常感谢先生【参考方案8】:

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

不过,在 javascript 中执行突出显示可能会更好。 jQuery 的 "contains" 选择器可能会帮助您避免替换标记元素的问题...

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

【讨论】:

以上是关于在搜索中突出显示多个关键字的主要内容,如果未能解决你的问题,请参考以下文章

突出搜索中的多个关键字

在 ASP.Net 中搜索关键字突出显示

从关键字搜索中突出显示数据网格上的所有匹配字符串/子字符串

怎么在一个word文档中 同时搜索多个关键字,并能高亮显示它们?有插件么 或者告诉我一个宏?

有没有办法突出显示 (g)Vim 中的多个搜索?

在 Android 中使用 Html.fromHtml() 突出显示文本颜色?