tags:

views:

560

answers:

2

I'm trying to highlight the search results but I want to include the surrounding text that is limited by the enclosing tags.

So if the $term is "cool" the preg_replace should end up with:

<div><span style="background: #f00">My hair cut so cool!</span></div>

Unfortunately my regex doesn't seem to capture the surrounding text, only the $term. The surrounding tags could be any kind of valid tag.

    0:  
    1:  $term = 'cool';
    2:  ob_start();
    3:

   10:  foreach($items as $item) {
   11:    // echoing results here
   12:    echo '<div>' . $item->text . '</div>';
   13:  }

   30:  $content = ob_get_contents();
   31:  ob_clean() ;
   32:
   33:  $pattern = "/(?<!<[^>])($term)/i";
   34:  $replace = "<span style=\"background: #f00\">$1</span>";
   35:  echo preg_replace($pattern, $replace, $content);
   36:

EDIT: The foreach loop is one of many and is located in a separate class. Because of this I can't do the replacement in the loop itself. Also it seems more efficient to process the final output instead of each loop over the data.

A: 

Why the need of preg_replace?

This is how i would have solved the problem:

Case 1: Highlight a substring of the result: Use strpos() or stripos() to get the index of the first occurrence in a string. Next: Get the substring from index-X to index+L+Y, where X and Y is definded constants that describe number of characters to be highlighted before and after the word, and L is the length of the word. Then apply some -tag around the generated substring.

Case 2: Highlight the hole tag: You can still do the search by strpos/stripos. Then devide the string into two parts: Part one will be the substring from zero to the pointer, and part two consist of the rest of the string. Then: Find last occurrense (strrpos/strripos) of '>' in string 1 and first occurense of '<' in string 2. Insert your highlighting, and enjoy ;)

Some people, when confronted with a problem, think "I know, I’ll use regular expressions." Now they have two problems - Jamie Zawinski

qualbeen
I like this. It is easier to understand since obviously I'm still new to regex-ing.
I'm getting real tired of the JZ quote, particularly in situations where a regex is a very easy solution.
Jan Goyvaerts
+2  A: 

Finding a term and everything up to the HTML tags before and after it is the same as finding the term an all characters before and after it that aren't angular brackets. This is trivial with a regex:

$pattern = "/[^<>]*$term[^<>]*/i";
$replace = "<span style=\"background: #f00\">$0</span>";
Jan Goyvaerts
Great website (http://www.regexguru.com). I shall study up more. Thank you!