{
A couple of nights ago I blogged about an implementation of a technique to replace multiple patterns in a string on a single pass. Steve Levithan had an entry on the approach (not mine in specific, just the approach and commenting on a few weaknesses). It inspired a few things out of me: first, making the multiple replace an extension method of the string class, and second to duplicate Steve's approach which enables a more robust model because you can use metasequences etc...
Here is the code (included the using statement since the use of ToArray() from the Dictionary key collection isn't available without System.Linq):
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
static class RegexExtender {
public static string MultiReplace(this string target, DictionaryreplacementDictionary) {
return Regex.Replace(target,
"(" + String.Join("|", replacementDictionary.Keys.ToArray()) + ")",
delegate(Match m) { return replacementDictionary[m.Value]; }
);
}
public static string LevithansMultiReplace(this string target, DictionaryreplacementDictionary)
{
foreach (string key in replacementDictionary.Keys) {
Regex r = new Regex(key, RegexOptions.None);
target = r.Replace(target, replacementDictionary[key]);
}
return target;
}
}
Here is some usage:
// the original approach, as an extension method
string x = "Holly was a hunter";
Dictionaryrdict = new Dictionary ();
rdict.Add("Holly", "Hannah");
rdict.Add("hunter", "hatter");
Console.WriteLine(x.MultiReplace(rdict));
// Steve's technique
rdict = new Dictionary();
rdict.Add(@"[A-z]", "x");
rdict.Add(@"\d", "y");
string test = "David is 33";
Console.WriteLine(test.LevithansMultiReplace(rdict));
That is: Dictionary<string, string> instead of just Dictionary.