4

So let's say I make a search on my website for "Tales of an Ancient Empire". My database is doing a full text search, and results come up. I have this function for the highlight thngy

function sublinhamos($text, $words) {

    // explode the phrase in words
    $wordsArray = explode(' ', $words); 

    // loop all searched words
    foreach($wordsArray as $word) {
        //highlight
        $text = str_ireplace($word, "<span class=\"highlight\">".strtoupper($word)."</span>", $text, $count);
    } 
    //right trows results
    return $text;
}

It's not too bad, but the problem here is because the seach terms is "Tales of an Ancient Empire", when the str_ireplace finds the already inserted SPAN's it encounters the "an" words from the search term, and break the SPAN tag.

I need the highlight to highlight parts of a word, and all words up to two characters minimum, but it's all good apart from the old SPAN encounter problem.

Any ideas please?

4 Answers 4

5

Well, to start I wouldn't use a span.

<mark></mark>

is the better element to use. It's purpose is for highlighting parts of text like this. See this article for more information.

Also, you can pass an array into str_replace, eg:

function sublinhamos($text, $words) {
    $wordsArray = array();
    $markedWords = array();
    // explode the phrase in words
    $wordsArray = explode(' ', $words); 

    foreach ($wordsArray as $k => $word) {
      $markedWords[$k]='<mark>'.$word.'</mark>';
    }

    $text = str_ireplace($wordsArray, $markedWords, $text);

    //right trows results
    return $text;
}
Sign up to request clarification or add additional context in comments.

7 Comments

@mishu he just noticed that. His solution is to not replace in a loop but with an array at once. I like it. +1
Well just tested it and strange enough having a result (created for testing) with the word mark on it, and searching for mark did not corrupted the output... So probably this is the answer to go...
Very nice, I just came across another issue, although nothing to do with @Nick answer. Take again the example "Tales Of An Ancient Empire" The word Ancient will be marked the first An, and the rest of the word will be kept unhighlighted... I imagine this is a whole new problem... Anyway accepted answer.. Thanks
You could order the wordsarray by size (biggest first) before the foreach loop. This should do it.
@Flo @Nick I found that sorting the order of the array works well for me. Made quite a few tests and almost all of them are good. Only found one bug Where you search for "Ma Mark". Where it breaks the <mark>. Although i don't see such a search being done ;) lol
|
1

You could instead replace it with a temporary string that will no be searched (eg. {{{ and }}}) like this:

$text = str_ireplace($word, "{{{".strtoupper($word)."}}}", $text, $count);

After marking all your hits you can just do a simple replace of the temporary strings to your span tags

Comments

0

You can use a preg_replace with negative look-behind instead:

$text = preg_replace('/(?<!<sp)(?<!<\/sp)(an)/i', '<span class="highlight">$1</span>', $text);

The first look-behind is for starting span tags and the second for ending tags. Possibly you can combine them into one, but not sure.

Comments

0

have you tried something like this?

$text = preg_replace("|($word)|", "<span class=\"highlight\">".strtoupper($word)."</span>", $text, $count);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.