About the author

Miron Abramson
Me
Software Engineer,
CTO at PixeliT
and .NET addicted for long time.
Open source projects:
MbCompression - Compression library

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2014

Creative Commons License

Blog Flux Directory
Technology Blogs - Blog Top Sites

Highlight search results in any page in the application

Recently I was working on part of an existing big project that one of it's main feature is searching (in this case it was medical info). There is search option in some different pages.  I was asked to add feature that 'highlight' the searching word/s in the search results. To do it with minimum changes for the existing code, I decided to do it using a 'Response Filter' that get the search word/s from the query and highligh it in the page. The 'highlight' is not more than to replace the 'searching word' with '<span style='background-color:yellow;color:black;'>searching word</span>'.

The idea was to get the html before it been send to the client, look for the 'searching words' and just replace them. The 'problem' is that we need to search the 'searching word' only in the text that is between the HTML tags and not within the tags. for that I used RegularExpression (ofcourse)and the not well know but powerfull class 'MatchEvaluator'.

How is it work:

First, we need to get the list of the searching words and concat them into one string seperates by '|' char.  The searching words are taken from the query string using the parameter 'highligh', and seperates by spaces (%20), or if it is exact phrase, it need to be between " (inverted commas).  For exmple, to highlight all the words 'searching' and 'words' in this article use this url: http://mironabramson.com/blog/post/2008/01/Highlight-search-results-in-any-page-in-the-application.aspx?highlight=searching%20words . To highligh the exact match 'searching words' use the url: http://mironabramson.com/blog/post/2008/01/Highlight-search-results-in-any-page-in-the-application.aspx?highlight=%22searching%20words%22 .   (To parse the searching words from the query string I used an old method I did long time ago 'GetSearchingWordsList' I'm sure it can be replace with RegularExpression version easly)

Second, we needs to find all the text that is not HTML tags. This will be done using RegularExpression:

 private static readonly Regex REGEX_TEXT_BETWEEN_TAGS = new Regex(@">\s*[^<]*<(?!/script)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

 private static string HighlightText(string html, string hightlightWords)
 {
        MatchEvaluatorWithParameter matchEvulator = new MatchEvaluatorWithParameter(hightlightWords);
        return REGEX_TEXT_BETWEEN_TAGS.Replace(html, new MatchEvaluator(matchEvulator.Found));
 }

 The 'MatchEvaluator' in this case means that for every match of the regular expression, excute the method matchEvulator.Found

Third, we needs to find in every match our search words and replace it with '<span style='background-color:yellow;color:black;'>match</span>''

 private class MatchEvaluatorWithParameter
 {
      string _parameter;
      public MatchEvaluatorWithParameter(string parameter)

      {
           _parameter = parameter;
      }
      public string Found(Match m)
      {
           Regex replace = new Regex(_parameter, RegexOptions.IgnoreCase);
           return replace.Replace(m.Value, new MatchEvaluator(this.Replace));
       }
       private String Replace(Match m)
       {
           return "<span style='background-color:yellow;color:black;'>" + m.Value + "</span>";
       }
 }

To implement this ResponseFilter, you can use a new HttpModule or you can just assign the filter in an existing module in your application.  Note that like every other ResponseFilter you use, it must be exclude and not be performed if the request come from MS-AJAX control. 

To add it to an existing module, just add the 'HighlighterFilter' class, and in your module event, add:

  if (!IsAjaxPostBackRequest(app.Context) && app.Request.QueryString["highlight"] != null) {
         app.Response.Filter = new HighlighterFilter(app.Response.Filter, app.Server.UrlDecode(app.Request.QueryString["highlight"]));
  }

(If you are using compression module as I do, note that the highlight filter must come after you assign the compression filter, so it will be excute before.)  Downloading the code will help undersdand the concept more easly (as always, see the code always help to understand)

Maybe you will not find this Highlight filter usefull for your needs, but I guess some people saw a nice and useful example of using the powerfull of RegularExpression with the class 'MatchEvaluator'.

HighlighterFilter.cs (8.52 kb)

Currently rated 4.0 by 4 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by Miron on Saturday, January 12, 2008 5:55 AM
Permalink | Comments (1) | Post RSSRSS comment feed