CodeIgniter's highlight_phrase() function, in the Text Helper library, looks like this:

/**
 * Phrase Highlighter
 *
 * Highlights a phrase within a text string
 *
 * @access  public
 * @param   string  the text string
 * @param   string  the phrase you'd like to highlight
 * @param   string  the openging tag to precede the phrase with
 * @param   string  the closing tag to end the phrase with
 * @return  string
 */
if ( ! function_exists('highlight_phrase'))
{
    function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
    {
        if ($str == '')
        {
            return '';
        }

        if ($phrase != '')
        {
            return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
        }

        return $str;
    }
}

However, the string I need to run it on is already fully-formatted HTML. What modification can I make to the preg_replace() so that it will not do replacements inside < and > tags. For example, if I were to pass in <a href="http://www.daniweb.com">Foo</a> as the string, and daniweb as the phrase to be wrapped, I don't want it to turn it into <a href="http://www.<strong>daniweb</strong>.com">Foo</a>. It should only work on text between > and <.

Recommended Answers

All 6 Replies

I used this in js:

"(?!<[^>]*?)" + myWord + "(?!([^<]*?>))"

to avoid highlighting in attributes. It looks if it is within tags, nothing more. Seems to work the same in PHP.

Sorry to post this here, but I can no longer CTRL+V to paste in Opera.

Thanks! Also, I think Ctrl+V should work now. Sorry about that.

I think Ctrl+V should work now

Appears so, thx ;)

pritaeas, did you by any chance have your < and > in reverse??

This is what ended up working for me ...

function highlight_search($string)
{   
    $query = fetch_search_query();

    if (!empty($query))
    {
        $replace = array();
        $with = array();

        foreach (explode(' ', $query) as $key => $query_word)
        {               
            $with[] = '<strong class="search">\1</strong>';
            $replace[] = "|(?![^<]+>)(\b$query_word\b)(?![^<]+>)|iu";
        }

        return preg_replace($replace, $with, $string);
    }

    return $string;
}

I stole the regex from CakePHP's highlight function, and then added in to check for word boundaries so that it would only match whole words.

commented: Thanks for sharing. +13

Well... not sure, I had to type it over, because the copy-paste didn't work at the time, and it's been over two years since I wrote that.

No worries. Sorry about the Ctrl+V thing not working for a few hours.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.