I had the same problem:
here's my solution:
//$string contains html tags
//$search_words is an array
//this function highlights the search words found in the text, but doesn't affect the html tags
function highlight_search($search_words,$string,$bgcolor='yellow')
{
$rawstrings = preg_split('#(<\/?)(\w+)([^>]*>)#mis', $string, -1, PREG_SPLIT_NO_EMPTY);
//this seperates the text from the html tags
//text is stored as elements of 'rawstrings'
foreach($search_words as $search_word)
{
foreach($rawstrings as $rawstring){
$test=eregi_replace("($search_word)",'<span style="background-color: '.$bgcolor.'">\\1</span>', $rawstring);
//if you find the searchtext in the rawstring, store both rawstring and highlighted string
if($test<>$rawstring){$targetstrings[]=$rawstring; $highlightstrings[]=$test;}
}
}
$count=count($targetstrings);
$i=0;
while($i<$count){
//now search the original tagged string, replacing the
unhighlighted text with the highlight tagged text
$string=str_replace($targetstrings[$i],$highlightstrings[$i], $string);
$i++;
}
return $string;
}