1

I am successfully highlighting the results but the problem I'm facing is that the code is duplicating the results. For instance, even when I have just one occurrence of "this random text", the code inserts duplicate results inside the excerpt in a strange way. Stuck here, please help. I have attached a screenshot to help understand the issue. You can also see from my text that the sentence now doesn't make sense because it's not finding and truncating properly so that only the paragraph containing the matching keyword appears. enter image description here

function wps_highlight_results($text){
     if(is_search()){
     $sr = get_query_var('s');
     $keys = explode(" ",$sr);
     $text = preg_replace('/('.implode('|', $keys) .')/iu', '<strong class="search-excerpt">'.$sr.'</strong>', $text);
     }
     return $text;
}
add_filter('the_excerpt', 'wps_highlight_results');
Anne Vandu
  • 103
  • 10
  • What are the actual values for `$keys` and `$sr`? It looks like you're searching for *any* of the words in `$keys` and replacing them with `$sr`. That means if `$sr = 'In the beginning'` then you will be replacing all instances of `in`, `the`, and `beginning` with `in the beginning`. – kmoser May 04 '20 at 06:03
  • what is your `$sr` value? – Gilang Pratama May 04 '20 at 06:08
  • 1
    Seems I'm conflicting myself. I don't want to replace like that. I am trying to get the paragraph that contains the search text to show up inside the excerpt so that it's something like this "You, Lord, `in the beginning` created the earth, and with your own hands you made the heavens." – Anne Vandu May 04 '20 at 06:10
  • Yeah, that's what I figured; see my answer. – kmoser May 04 '20 at 06:12

1 Answers1

2

Assuming you want to replace all instances of the search string (e.g. in the beginning) with <strong class="search-excerpt">in the beginning</strong> then you'll need to change your code:

$text = preg_replace(
    preg_quote("/$sr/iu"),
    '<strong class="search-excerpt">'.$sr.'</strong>',
    $text
);

I've added the call to preg_quote() to make sure any regexp chars that might be in $sr are properly escaped.

kmoser
  • 8,780
  • 3
  • 24
  • 40
  • Note that this doesn't account for different whitespace between words, e.g. `in the` (one space) won't match `in the` (two spaces). If you want to account for that you'll have to modify the regexp. – kmoser May 04 '20 at 06:14
  • Yes, adding the code you gave above works. How do I focus on the text deep within the content? I need to bring it up to show in the excerpt. Any pointers that could help? Only matching results that are in the first few paragraph shows. Sorry If this is much ask. Thank you for the above answer as well. – Anne Vandu May 04 '20 at 06:25
  • 1
    To above answer which is correct btw. try use this regex: "/\b($sr)\b/i" – pc_ May 04 '20 at 06:28
  • 1
    @Maryongubo As I said, any exact match should be replaced. If you are finding strings that look like they should match but aren't, it's probably due to differences in whitespace between words as I mentioned in my previous comment. Can you confirm that this is the case? – kmoser May 04 '20 at 06:30
  • You can also clean your match with something like this before regex: $sr= quotemeta(str_replace(array('+', '-', '*', '"', '(', ')'), '', $sr)); – pc_ May 04 '20 at 06:32
  • This is what I meant - the excerpt by default shows the like 5 paragraphs. So if they search term which I'm highlighting is not in those paragraphs then it doesn't show up. The code you gave is working, no issues. What I'm struggling with displaying the search term even if it's not among the first paragraphs of my excerpts. Example, `in the beginning` could be in the last paragraph of my text. In this case it won't show up in my excerpt because it's trimmed by default though it will actually be highlighted by your code above. – Anne Vandu May 04 '20 at 06:36
  • If you're only showing an excerpt but the match appears after the excerpt, and you want to show that match, you'll have to show the entire text, not just the excerpt. – kmoser May 04 '20 at 06:39
  • Okay, I'd thought there was a way of truncating it where the target text appears. – Anne Vandu May 04 '20 at 06:45
  • 1
    Change the regexp to: `'/.{0,100}' . preg_quote($sr) . '.{0,100}/iu'`. This will cause it to show up to 100 chars before and after the matched string, i.e. not the entire contents of `$sr`. – kmoser May 04 '20 at 06:52
  • You would have to show me the exact code you tried. – kmoser May 04 '20 at 13:22
  • This is what I added `function wps_highlight_results($text){ if(is_search()){ $sr = get_query_var('s'); $text = preg_replace(preg_quote('/.{0,100}' . preg_quote($sr) . '.{0,100}/iu'),''.$sr.'',$text); } return $text; } add_filter('the_excerpt', 'wps_highlight_results');` – Anne Vandu May 04 '20 at 14:10
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/213111/discussion-between-kmoser-and-mary-ongubo). – kmoser May 04 '20 at 18:29
  • Is this what are you after https://stackoverflow.com/questions/13065215/php-get-10-words-around-a-search-phrase?rq=1 – pc_ May 05 '20 at 05:21