突出搜索中的多个关键字

问题描述 投票:7回答:8

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

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

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

php html search arrays highlight
8个回答
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';

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


16
投票

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

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

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
投票

Highlight multiple keywords in search including umlauts

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

Example

搜索词: 苏shamp

文本: 阳光闪亮的洗发水

结果: 阳光闪亮的洗发水


The code I've used:

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

1
投票

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

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

0
投票

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

通过javascript执行突出显示可能会更好。 jQuery“contains”选择器可能有助于避免在你去的时候替换标记元素的问题...

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


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.