1

I am displaying search results on site where users can search for specific keyword, words.

On results page I am trying to Highlight the searched words , in the result. So user can get idea which words matched where.

e.g.

if user searches for : mango

the resulting item original : This Post contains Mango.

the resulting output I want of highlighted item : This Post contains <strong>Mango</strong>

I am using it like this.

<?php

//highlight all words 
function highlight_words( $title, $searched_words_array) {
    // loop through searched_words_array
    foreach( $searched_words_array as $searched_word ) {
        $title = highlight_word( $title, $searched_word); // highlight word
    }

    return $title; // return highlighted data
}

//highlight single word with color
function highlight_word( $title, $searched_word) {
    $replace = '<strong>' . $searched_word . '</strong>'; // create replacement
    $title = str_ireplace( $searched_word, $replace, $title ); // replace content
    return $title; // return highlighted data
}

I am getting searched words from Sphinx Search Engine , the issue is Sphinx returns entered/macthed words in lowercase.

So by using above code , my

results becomes : This Post contains <strong>mango</strong>

*notice the m from mango got lowercase.

So my question is how can I Highlight word i.e. wrap <strong> & </strong> around the words matching the Searched words ? without loosing its textcase ?

*ppl. its not same questions as how to highlight search results , I am asking my keywords array is in lowercase and using above method the original word gets replaced by lowercase word. so how can I stop that ? the other question link will face this too , because the searched keywords are in lowercase. and using str_ireplace it will match it and replace it with lowercase word.


update :

i have combined various code snippets to get what i was expecting code to do., for now its working great.

function strong_words( $title, $searched_words_array) {
    //for all words in array
    foreach ($searched_words_array as $word){

        $lastPos = 0;
        $positions = array();
        //find all positions of word
        while (($lastPos = stripos($title, $word, $lastPos))!== false) {
           $positions[] = $lastPos;
           $lastPos = $lastPos + strlen($word);
        }
        //reverse sort numeric array 
        rsort($positions);

        // highlight all occurances
        foreach ($positions as $pos) {
            $title = strong_word($title , $word, $pos);
        }
    }

//apply strong html code to occurances  
$title = str_replace('#####','</strong>',$title);
$title = str_replace('*****','<strong>',$title);
return $title; // return highlighted data
}


function strong_word($title , $word, $pos){
//ugly hack to not use <strong> , </strong> here directly, as it can get replaced if searched word contains charcters from strong
$title = substr_replace($title, '#####', $pos+strlen($word) , 0) ;
$title = substr_replace($title, '*****', $pos , 0) ;
return $title;
} 

$title = 'This is Great Mango00lk mango';
$words = array('man','a' , 'go','is','g', 'strong') ;

echo strong_words($title,$words);
Community
  • 1
  • 1
  • 1
    possible duplicate of [how to highlight search results](http://stackoverflow.com/questions/10313332/how-to-highlight-search-results) – B001ᛦ Sep 08 '15 at 08:42
  • @bub the main function is modified from that link, becuase i just wanted to use single color and , its not same question. –  Sep 08 '15 at 08:45

4 Answers4

1

Regex solution:

function highlight_word( $title, $searched_word) {
    return preg_replace('#('.$searched_word.')#i','<strong>\1<strong>',$title) ;
}

Just be wary of special characters that may be interpreted as meta characters in $searched_word

gyaani_guy
  • 3,191
  • 8
  • 43
  • 51
  • Thanks for your reply, i am looking for something not regex, as its slow in performance. –  Sep 08 '15 at 13:10
1

Here's a code snippet I wrote a while back that's working to do exactly what you want:

if(stripos($result->question, $word) !== FALSE){
    $word_to_highlight = substr($result->question, stripos($result->question, $word), strlen($word));
    $result->question = str_replace($word_to_highlight, '<span class="search-term">'.$word_to_highlight.'</span>', $result->question);
}
Jeremy Jackson
  • 2,247
  • 15
  • 24
  • Thanks, this is working but for single occurrence of needle i.e. first occurrence. –  Sep 08 '15 at 13:29
0
//will find all occurances of all words and make them strong in html
function strong_words( $title, $searched_words_array) {
    //for all words in array
    foreach ($searched_words_array as $word){

        $lastPos = 0;
        $positions = array();
        //find all positions of word
        while (($lastPos = stripos($title, $word, $lastPos))!== false) {
           $positions[] = $lastPos;
           $lastPos = $lastPos + strlen($word);
        }
        //reverse sort numeric array 
        rsort($positions);

        // highlight all occurances
        foreach ($positions as $pos) {
            $title = strong_word($title , $word, $pos);
        }
    }

//apply strong html code to occurances  
$title = str_replace('#####','</strong>',$title);
$title = str_replace('*****','<strong>',$title);
return $title; // return highlighted data
}


function strong_word($title , $word, $pos){
//ugly hack to not use <strong> , </strong> here directly, as it can get replaced if searched word contains charcters from strong
$title = substr_replace($title, '#####', $pos+strlen($word) , 0) ;
$title = substr_replace($title, '*****', $pos , 0) ;
return $title;
} 


$title = 'This is Great Mango00lk mango';
$word = array('man','a' , 'go','is','g', 'strong') ;

echo strong_words($title,$word);

This code will find all occurrences of all words and make them strong in html while keeping original text case.

-1

function highlight_word( $content, $word, $color ) {
    $replace = '<span style="background-color: ' . $color . ';">' . $word . '</span>'; // create replacement
    $content = str_replace( $word, $replace, $content ); // replace content

    return $content; // return highlighted data
}

function highlight_words( $content, $words, $colors ) {
    $color_index = 0; // index of color (assuming it's an array)

    // loop through words
    foreach( $words as $word ) {
        $content = highlight_word( $content, $word, $colors[$color_index] ); // highlight word
        $color_index = ( $color_index + 1 ) % count( $colors ); // get next color index
    }

    return $content; // return highlighted data
}



// words to find
$words = array(
    'normal',
    'text'
);

// colors to use
$colors = array(
    '#88ccff',
    '#cc88ff'
);

// faking your results_text
$results_text = array(
    array(
        'ab'    => 'AB #1',
        'cd'    => 'Some normal text with normal words isn\'t abnormal at all'
    ), array(
        'ab'    => 'AB #2',
        'cd'    => 'This is another text containing very normal content'
    )
);

// loop through results (assuming $output1 is true)
foreach( $results_text as $result ) {
    $result['cd'] = highlight_words( $result['cd'], $words, $colors );

    echo '<fieldset><p>ab: ' . $result['ab'] . '<br />cd: ' . $result['cd'] . '</p></fieldset>';
}

Original link check here

Community
  • 1
  • 1
Ananta Prasad
  • 3,655
  • 3
  • 23
  • 35