views:

236

answers:

3

i'm using this code to highlight search keywords:

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

however, this highlights only one keyword. if the user enters more than one keyword, it will narrow down the search but no word is highlighted. how can i highlight more than one word?

A: 

Splits your search query up into words, then highlight each words separately.

It might work out better to perform the highlighting in javascript though. jQuery's "contains" selector will probably help avoid problems of replacing markup elements as you go...

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

rikh
+1  A: 

Assuming the words are entered as a space seperated string you can just use explode

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

Although if you want to ensure there are not multiple spaces, you may want to remove them from the string first

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

You do then have to generate a replacement array

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

Then

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

So putting it togther

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);
}
Yacoby
thank you for your comment.
fuz3d
+3  A: 

regular expressions is the way to go!

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

To match in a case-insensitive manner, add 'i' to the regular expression

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

NB: for non-enlish letters like "ä" the results may vary depending on the locale.

stereofrog
excellent. thank you.
fuz3d
how do i make it case in-sensitive? if the user types in 'good', it will only show 'good' and not 'Good'.
fuz3d
see update......
stereofrog
thanks. last question: if the user types in 'good', it will show all the results highlighting the keyword 'good'. however, it won't highlight 'good' of the word 'goodness' altho it will show up in the result.
fuz3d
if you want to highlight parts of words as well, remove `\\b` (word boundary sign) from the regular expressions.
stereofrog
thank you very much!
fuz3d