Published by breki on 05 Jan 2009 at 05:46 pm
Visiting Regex.Replace() Method And MatchEvaluator Delegate
In his post about creating string formatting function which would use named parameters instead of numbered ones like {0}, {1} etc, Phil Haack mentions perhaps little known, but very useful method of the Regex class: Replace() method, specifically the override which uses MatchEvaluator delegate.
I first used this method few days ago when I was implementing labeling of map elements for GroundTruth, a new mapmaking tool for Garmin which I’m currently working on. The idea was to provide something like a format string which would tell the tool how to construct a label for map elements (roads, cities etc). One example would be to generate map label of a mountain peak with an attached elevation: “Mount Everest, 8848 M“.
The solution was to provide special functions (or properties) which would expand to actual values of map element’s tags, but by also taking account of the context (for example, do we show elevation in meters or feet?). These functions would be encoded in the string in form of $FunctionName. This is where Regex.Replace() comes in handy:
format,
delegate(Match match)
{
string functionName = match.Groups["function"].Value;
if (false == registeredFunctions.ContainsKey(functionName))
throw new ArgumentException(
String.Format(
CultureInfo.InvariantCulture,
"Unknown label building function ‘{0}’",
functionName));
ILabelBuildingFunction function = registeredFunctions[functionName];
string result = function.Calculate(mapMakerSettings, osmObject, osmTag);
return result;
});
So what are we doing here? We are telling Regex to give us each Regex match and we will then return a replacement string for it. The anonymous delegate extracts the name of the function from this Match and looks it up in the dictionary of supported functions. Since each function has a corresponding object, we call on this object to give us an actual value of the function (Calculate() method). We then return this value to Regex as a replacement.
The regexFunction is defined as a static class member:
RegexOptions.Compiled | RegexOptions.ExplicitCapture);
Creating Regex objects is expensive, so it’s better to instantiate them once as static members. Using RegexOptions.Compiled is also recommended, as is reading Jeff Atwood’s post about it.



Reflective Perspective - Chris Alcock » The Morning Brew #258 on 06 Jan 2009 at 9:53 #
[...] Visiting Regex.Replace() Method And MatchEvaluator Delegate – Igor Brejc follows on from Phil Haack’s post yesterday about named string formatting functions with some exploration of some of the clever things regular expressions can do. [...]