Highlighting Keywords Found In Search Results

A common question in the forums is how to highlight key words found in search results. Here's an extension method that does that, both for partial matches, or whole word matches.


/// <summary>
/// Wraps matched strings in HTML span elements styled with a background-color
/// </summary>
/// <param name="text"></param>
/// <param name="keywords">Comma-separated list of strings to be highlighted</param>
/// <param name="cssClass">The Css color to apply</param>
/// <param name="fullMatch">false for returning all matches, true for whole word matches only</param>
/// <returns>string</returns>
public static string HighlightKeyWords(this string text, string keywords, string cssClass, bool fullMatch)
{
  if (text == String.Empty || keywords == String.Empty || cssClass == String.Empty)
    return text;
  var words = keywords.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
  if (!fullMatch)
    return words.Select(word => word.Trim()).Aggregate(text,
                 (current, pattern) =>
                 Regex.Replace(current, 
                                 pattern,
                                   string.Format("<span style=\"background-color:{0}\">{1}</span>", 
                                   cssClass, 
                                   "$0"),
                                   RegexOptions.IgnoreCase));
  return words.Select(word => "\\b" + word.Trim() + "\\b")
              .Aggregate(text,(current, pattern) => 
                        Regex.Replace(current, 
                        pattern,
                          string.Format("<span style=\"background-color:{0}\">{1}</span>", 
                          cssClass, 
                          "$0"),                                           
                          RegexOptions.IgnoreCase));

}

The method uses Regex, so when you add it to a class, make sure you reference System.Text.RegularExpressions. As you can see, it applies a background colour to a span, so a valid CSS colour needs to be passed in. I haven't added any validation to the method to check for a valid colour, but it wouldn't be too difficult to do. For Hex colours, the test would be 6 characters, numbers (0-9) or letters (a-f). RGB colours are composed of 3 sets of numbers between 0 and 255. And there is a finite list of 16 HTML colour names, although you might want to accept SVGA colour names too, which are supported by most browsers. More details on colours can be found here. Alternatively, you can alter the html that this method produces so that the argument can be CSS class name rather than a colour.

As it is, here's how to use it within MVC where I shall pass in the following to the View:


ViewData["temp"] = "aster faster plaster mastering forecaster.";

Within the View itself, using the full word matches option:


<div><%= ViewData["temp"].ToString().HighlightKeyWords("aster", "yellow", true)%></div>


which results in the following:

Changing true to false results nicely in this:

Using the method in Web Forms is easy too. Assuming that a search result has been passed to a DataBound control with an ItemTemplate, here's how it might look:


<ItemTemplate>
   <asp:Label ID="Label1" runat="server" Text='<%# Eval("mySearchResult").ToString().HighlightKeyWords("aster", "yellow", true) %>' />
</ItemTemplate>

Date Posted:
Last Updated:
Posted by:
Total Views to date: 36875

6 Comments

- anooj

Nice,,,,It's very useful.

- dimitris

Very nice, solid implementation. Came in handy thank you very much.

- Atit

Hi,

The solution provided to highlight the terms on web page works okay for single terms. But it is not working if there is a space between the terms.

e.g. searches fine if "companies" is the input
but doesn't work if "companies act" is the input

- kishor

it will give an error if I give a single ( or ) as a keyword

- leo

Hi there,

do you think it would be possible to improve this code for matching provided keywords ignoring accented letters?
for examples if I specify "coupe" as my keyword and I'd like to match coupé in a phrase contains "coupé".

Do you think it would be possible?
I can't find an elegant way.

Regards
Leo

- Mike

@Leo

Thre's a solution to that in: this Stackoverflow post
Add your comment

If you have any comments to make about this article, please use this form to do so. Make sure that your comment relates specifically to the article above. More general comments can be posted through the form on the Contact page.

Please note, all comments are moderated, and I end up deleting quite a lot. The kind of things that will ensure your comment is deleted without ever seeing the light of day are as follows:

  • Requests to fix your code (post a question to forums.asp.net instead, please)
  • Gratuitous links to your own site or product
  • Anything abusive or libellous
  • Spam

I do not pass email addresses on to spammers, so a valid one will assist me in responding to you personally if required.

Recent Comments

hosein ey 2/25/2015 1:56 PM
In response to ASP.NET MVC 5 with EF 6 - Working With Files
tnx for this article do you think next version of entityframework support's the sql server and ?...

Saywer Ford 2/25/2015 5:15 AM
In response to Optimising ASP.NET Web Pages Sites - Bundling And Minification
Great Article. I did everything right and working fine. How about page specific js files. Lets I...

Saravanan 2/24/2015 10:54 AM
In response to Optimising ASP.NET Web Pages Sites - Bundling And Minification
Hi, Great article about the Bundling and minification. Regards the caching as you mentioned the...

Justin 2/24/2015 10:43 AM
In response to Scheduled Tasks In ASP.NET With Quartz.Net
I'm having the same problem as Ingmar. Everything is working fine locally in Visual Studio, but I it...

Logan Mudlo 2/23/2015 4:59 PM
In response to WebMatrix - A First Application
Is there a way to prevent the automatic close on a Database.Open() call?...

Mog0 2/23/2015 11:16 AM
In response to ASP.NET MVC 5 with EF 6 - Working With Files
Probably a silly question but why did you disable cascade delete and implement it yourself?...

Jose-Maria 2/19/2015 3:29 PM
In response to Migrating From Razor Web Pages To ASP.NET MVC 5 - Views and Controllers
Just great ! Many thanks Mike....

Satyabrata Mohapatra 2/19/2015 12:02 PM
In response to Migrating From Razor Web Pages To ASP.NET MVC 5 - Views and Controllers
This is great!!...

Ryan Helmoski 2/19/2015 10:24 AM
In response to Conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value
Thank you!...

Harsha 2/19/2015 8:27 AM
In response to iTextSharp - Adding Text with Chunks, Phrases and Paragraphs
Hi, Can text area be created so that I can type text in the area in pdf document? We have Add text...