michaellunsford Posted January 17, 2007 Share Posted January 17, 2007 well, I started this in the regular PHP section, but it no longer fits there. Suffice it to say, I'm trying to take individual search terms that are being $_POSTed and highlighting them in the search results.The [url=http://www.phpfreaks.com/forums/index.php/topic,122532.0.html]Original Post[/url] talked about using str_replace to handle this. New problem, though, when the same search terms show up inside a HTML tag (like <img src="search_term">).I'm trying "/\b(?!<.+?>)search_term\b/" -- but it's still finding "search_term" inside <img src="search_term">.Thanks! Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/ Share on other sites More sharing options...
effigy Posted January 17, 2007 Share Posted January 17, 2007 Either [url=http://www.phpfreaks.com/forums/index.php/topic,99040.msg389868.html#msg389868]separate the tags from the content and process[/url], or just analyze the non-tagged content:[code]<pre><?php $tests = array( '<img src="search_term">', '<a>search_term</a>', '<a>Xsearch_termX</a>', ); $term = 'search_term'; echo "Searching for <b>$term</b>...<br>"; foreach ($tests as $test) { echo htmlspecialchars($test), ' => '; $test = preg_replace_callback( '/>(.+?)</', create_function( '$matches', 'return preg_replace("/\b(' . preg_quote($term) . ')\b/", "<b>\\\1</b>", $matches[0]);' ), $test ); echo htmlspecialchars($test), '<br>'; }?></pre>[/code] Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163134 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 Wow, that's intense. All kinds of functions I've never heard of. In fact after reading the manual page on create_function(), I still don't understand it. $matches doesn't exist anywhere outside of create_function()???Anyway, it's doing the same thing my original preg_replace() was doing (finding matches inside tags). Here's the new function, minus the array stuff:[code]<?php$test="<table>\r\n<tr>\r\n\t<td><img src=\"somestring.jpg\" alt=\"\"></td>\r\n</tr>\r\n<tr>\r\n\t<td>somestring</td>\r\n</tr>\r\n</table>\r\n";$term = 'somestring';$test = preg_replace_callback( '/>(.+?)</', create_function( '$matches', 'return preg_replace("/\b(' . preg_quote($term) . ')\b/", "<span style=\"background:#FF0;\">\\\1</span>", $matches[0]);' ), $test ); echo $test;?>[/code]and the output[code]<table><tr> <td><img src="<span style="background:#FF0;">somestring</span>.jpg" alt=""></td></tr><tr> <td><span style="background:#FF0;">somestring</span></td></tr></table>[/code] Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163296 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 hey, check this out...[code]<?php$test="<table>\r\n<tr>\r\n\t<td><img src=\"somestring.jpg\" alt=\"\"></td>\r\n</tr>\r\n<tr>\r\n\t<td>somestring</td>\r\n</tr>\r\n</table>\r\n";preg_match("/>(.+?)</",$test,$new_array);print_r($new_array);?>[/code]result:[code]Array( [0] => ><img src="somestring.jpg" alt="">< [1] => <img src="somestring.jpg" alt="">)[/code] Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163303 Share on other sites More sharing options...
effigy Posted January 18, 2007 Share Posted January 18, 2007 Ah, of course. Change[tt] />(.+?)</ [/tt]to[tt] />(.*?)</[/tt]. Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163311 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 First, let me say it works great!However, I don't understand why />(.*?)</ is returning ">somestring<" instead of just "somestring" ??? Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163363 Share on other sites More sharing options...
effigy Posted January 18, 2007 Share Posted January 18, 2007 Where? The entire match includes the angle brackets, but the 1st capture does not. It depends on which part you're using. Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163392 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 here's what />(.*?)</ matches in the example:[code] [0] => Array ( [0] => >< [1] => >< [2] => > < [3] => >somestring< [4] => > < ) [1] => Array ( [0] => [1] => [2] => [3] => somestring [4] => )[/code] Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163397 Share on other sites More sharing options...
effigy Posted January 18, 2007 Share Posted January 18, 2007 A better alternative might be [tt]/(?<=>)([^<]+)/[/tt]. Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163405 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 Dude, it's magic. One more thing that is not quite working right: MySQL is returning case insensitive results. Is there any way to make [code=php:0]'/\b(' . preg_quote($newstring) . ')\b/'[/code] case insensitive?Also, if you're willing to educate, I'm struggling to follow this part of the code. (?<=>) is a lookbehind for ">"? It's working perfectly to locate the text I'm searching for -- even text that isn't preceeded by ">". I don't get it, is lookbehind optional? Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163454 Share on other sites More sharing options...
effigy Posted January 18, 2007 Share Posted January 18, 2007 Yes, put an "i" after the closing delimiter: [tt]/pattern/i[/tt]You are correct about the lookbehind; however, they are not optional (by default). Why do you think it is matching text that isn't preceded by ">"? Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163520 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 It's finding the search term, even after newlines. So, I guess (?<=>) evades newlines, too? Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163642 Share on other sites More sharing options...
effigy Posted January 18, 2007 Share Posted January 18, 2007 [tt]([^<]+) [/tt]is capturing the CRs and NLs, and[tt] (?<=>) [/tt]is still anchoring at ">". Observe:[code]<pre><?php $test = "<table>\r\n<tr>\r\n\t<td><img src=\"somestring.jpg\" alt=\"\"></td>\r\n</tr>\r\n<tr>\r\n\t<td>somestring</td>\r\n</tr>\r\n</table>\r\n"; preg_match_all('/(?<=>)([^<]+)/', $test, $matches); $replace = array( "\n" => '\n', "\r" => '\r', ); foreach ($matches as &$array) { foreach ($array as &$match) { $match = preg_replace('/([\r\n])/e', '$replace["\1"]', $match); } } print_r($matches);?></pre>[/code] Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163705 Share on other sites More sharing options...
michaellunsford Posted January 18, 2007 Author Share Posted January 18, 2007 ahhh... I should have known that :-[ all this late night programming must be killing brain cells :) Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-163712 Share on other sites More sharing options...
fataqui Posted December 31, 2007 Share Posted December 31, 2007 I do like this... Â <?php $arrayofwords = array (); $arrayofwords[0] = "This"; $arrayofwords[1] = "text"; $arrayofwords[2] = "need"; $arrayofwords[3] = "words"; $str = 'This is my <img src="" title="This image text"> long text <a href="#">words</a> where I need to highlight words in the HTML text.'; $str = preg_replace ( "/(?!(?:[^<]+>|[^>]+<\/a>))\b(" . implode ( '|', $arrayofwords ) . ")\b/is", "<strong>\\1</strong>", $str ); echo $str; ?> Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-426625 Share on other sites More sharing options...
lwc Posted July 28, 2008 Share Posted July 28, 2008 Of course, your code only works in sites with strictly Latin words. Otherwise, see this. Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-602130 Share on other sites More sharing options...
ddrudik Posted October 29, 2008 Share Posted October 29, 2008 I would suggest: search_term(?!(?=[^<>]*>)) Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-677127 Share on other sites More sharing options...
ddrudik Posted October 30, 2008 Share Posted October 30, 2008 Also, if you want to exclude search_term from within head/script/a blocks as well as from within tags: $html=preg_replace_callback('~(<head>.*?</head>|<script\s[^>]*>.*?</script>|<a\s[^>]*>.*?</a>)|search_term(?!(?=[^<>]*>))~is',create_function('$matches','return isset($matches[1]) ? $matches[1] : "<strong>$matches[0]</strong>" ;'),$html); Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-678244 Share on other sites More sharing options...
lwc Posted December 16, 2008 Share Posted December 16, 2008 I do like this... I like this too. But can you deal with "<" and ">" too? Link to comment https://forums.phpfreaks.com/topic/34619-highlighting-search-terms/#findComment-716913 Share on other sites More sharing options...
Recommended Posts