tags:

views:

320

answers:

3

I have a case where I'm returning database results and displaying them on a page based on a search term. This part is working fine, but I want to hightlight these search terms by wrapping them in span tags. I started to write a function that I called on each result that used the str_replace function, but then it dawned on me that this would also affect any text that is in HTML tags. Does anybody have a function they use to do this effectively? I'm using PHP 4. Thanks!

+2  A: 

I've once written a search in Perl, did it like this (did a little translation to PHP):

// Split up the full page content in pieces without `<` and `>`
preg_match_all("/([^<>]+)/", $pageContent, $matches);
foreach ($matches as $val) {
    // Just print the $val if it was between < and >
    if (preg_match("/<$val>/", $pageContent) { print "<$val>"; }
    else {
       // Do the replace
       print str_replace( "$searchString", "<span>$searchString</span>", $val);
   }
}

You could avoid using Regular Expressions if:

 // Split up the full page content in pieces with `<`
 $matches = split("<", $pageContent);
 foreach ($matches as $val) {
    // Just print the $val if it was between < and >
    if (stristr($pageContent, "<$val")) { print "<$val"; }
    else {
       // Do the replace
       print str_replace( "$searchString", "<span>$searchString</span>", $val);
   }
}

Did not test it, but should be something like this.

To1ne
str_replace is case sensitive. I would like to use a case insensitive replace but I'm only using PHP4 so I can't use str_ireplace.
Mike C.
A: 

If you are returning the results and displaying them, then shouldn't you have access to the raw data before it gets churned out in html? If so, then do your modifying on the raw data by adding the span tags in there.

If you are saying that your raw data may already have html in it, you may be able to use a regex to detect whether you are inside an html tag, and use preg_replace instead of str_replace.

Other options:

--load results into a dom parser and only do replace operations on the leaf text nodes

-- write your own parser to keep track of if you are inside an html tag or not

-- yank out all the HTML tags from your results, put in placeholders like " [[[tag1]]] balha blah blah [[[tag2]]]" then do your replace on the remaining text, then substitute your tags back in

Zak
preg_replace was the answer. I had to use the i modified to make it case-insensitive, like so: $pattern = '/('.getSearchTerm().')/i';
Mike C.
+3  A: 

I'd go for highlight with javascript

http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

$(document).ready(function(){
$('#your_results_list').removeHighlight().highlight('search_word');
}

this way you don't mess with the source, user can turn highlight if you want, etc.

zalew