Friday, May 9, 2008

Passing Additional Parameters to MatchEvaluator

I think the easiest way to explain what this blog entry is about is to just give a real life situation I had. I am using Microsoft’s LogParser (what a great tool) to pull all Windows event logs from different server into one SQL Server database. LogParser does this quite nicely. A side note: I noticed that by default –formatMsg is set to ON which causes end of line characters to go away. This can be annoying when you want to display formatted message from the Windows Event log. I highly recommend setting –formatMsg to OFF if you want the Message column in the Windows EventLog to be formatted as you see it in the built in Event Viewer. With that said, I am not going to go into how to do this because it is not important to this blog entry.

What is important is that you can assume you have a string and you want to use regular expressions to do a search and replace on keywords. One of the big problems is that if you create an actual delegate method for the MatchEvaluator to call it can only have one parameter and that is the one it is expect. This is an issue if you need to pass additional information such as the css style (in my case) to this method. An alternate way of doing this in .Net 2.0 or later is to take advantage of Anonymous methods (See http://msdn.microsoft.com/en-us/library/0yw3tz5k(VS.80).aspx for more information). Anonymous methods allow you to cross traditional scope boundaries of variables as use the variables of the method that has defined the Anonymous method.

public string HighlightKeyWord(string bodyOfText, string regex, string cssStyle)
{
try
{
   bodyOfText = Regex.Replace(bodyOfText, regex,
      new MatchEvaluator(
         delegate(Match m) { return string.Format("<span class=\"{0}\">{1}</span>", cssStyle, m.Value); }
      )
   );
} // end try
catch (ArgumentException ex){ // Syntax error in the regular expression }
return bodyOfText;
}

Notice in this code cssStyle variable is referenced in the anonymous method even though it is defined in the parent method.

Here is an example of how to use this code:

public string HighlightUserName(string text)
{
   return HighlightKeyWord(text, "mydomain\\\\\\w+", "highlightUserName");
}

In this example of usage, I assume that there is a css class called highlightUserName. It would change the text such that all places that have mydomain\myusername in the text would be changed to <span class=”highlightUserName”>mydomain\myusername</span> and thus show as formatted text in the browser.