Tuesday, October 19, 2004

Regex.Replace()

Many times, we have a need for creating templates with key areas that are tagged for replacement.  An example would be a mail-merge type form letter.

Dear [NAME],

We have reviewed your account: [ACCOUNTNUMBER].  The issue you identified has been resolved.  [COMMENTS]

Sincerely,
[COMPANYNAME]

Most of the time, this is done with some brute force string.Replace command for every possible field that may have been tagged in the document.

        public string MergeFields(string text)
{
text = text.Replace("[NAME]", _name);
text = text.Replace("[ACCOUNTNUMBER"], _accountNumber);
text = text.Replace("[COMMENTS]", _comments);
text = text.Replace("[COMPANYNAME]", _companyName);
}


This will work, but as the number of possible fields increases, your MergeFields method gets incredibly unwieldy.  Enter Regex.Replace.



        public string MergeFields(string text)
{
string fieldPattern = @"\[(?<Field>[A-Z]+)\]";
return Regex.Replace(text, fieldPattern, new MatchEvaluator(GetFieldValue));
}


        private static Hashtable _fieldProps = new Hashtable();
private string GetFieldValue(Match m)
{
string fieldName = m.Groups["Field"].Value;
PropertyInfo propInfo = (PropertyInfo)_fieldProps[fieldName];
if (propInfo == null)
{
Type type = typeof(RequestMailer);
propInfo = type.GetProperty(fieldName, typeof(string));
if (propInfo == null)
throw new ArgumentException(m.Value + " is not a valid property.");
_fieldProps.Add(fieldName, propInfo);
}
return (string)propInfo.GetValue(this, new object[0]);
}


So what's happening?  The Regex Replace method takes a regular expression pattern.  In this case it finds all occurences of [ALLCAPS].  When it finds a match, it passes the matched value to our GetFieldValue method.  The GetFieldValue method uses reflection to find the property and get the value from the property.



How does this help?  As we have the need to add more and more new custom properties, all we have to do is add the property itself.  The replacing methods do not need to be updated for the new properties to be used.



Technorati Tags: ,