says: "end of 2008, and I did no shyt.."

Scenario: I have a number of patterns that I need to check and replace in a string. I don’t want to transverse the string and play with characters and length. What other option I have?

Answer: Ah, RegularExpression is your saviour today.

Say you have defined one pattern '{D:mmddyy}' so that you can have a dynamic date part in the string value. Your string variable :

string myValue = "My mum say i am a good boy on {D:ddMMMyyy}";

Firstly, you need to declare your pattern in regular expression format, and it should be:

string myPattern = "(?<myPat>{d:[mdy]+})";

Here we use (?<name>=pattern), which is what we called Grouping Construct to group pattern together. We easily retrieve the value with the grouping as you can see later. Once you have the pattern ready, we are ready to utilize .NET RegularExpression (RegEx)

MatchCollection colMatches = RegEx.Matches(myValue, myPattern, RegExOptions.IgnoreCase);

Note that I use RegExOptions.IgnoreCase here because I am lazy to define all cases of date-time formatting characters. And MatchCollection is used as I expect to have multiple similar patterns in my string. If you don’t, you can replace it with:

Match pMatch = RegEx.Match(myValue, myPattern, RegExOptions.IgnoreCase);

If everything is ok, we should have some results.

foreach (Match pMatch in colMatches)
{
	Console.WriteLine("{0} is found at {1}", pMatch.Value, pMatch.Index);
}

pMatch.Value should give you the pattern found in the string, and pMatch.Index is the index of occurence. Once you have this information, you can do anything you can!

Extending from above, I use back similar technique to parse the matched pattern.

string PATTERN_IN_PATTERN = @"{(?<key>\\w+)(:(?<pattern>\\w+))?}";
Match pInnerMatch = Regex.Match(pMatch.Value,
					PATTERN_IN_PATTERN, RegexOptions.IgnoreCase);

if (pInnerMatch.Success) //if there is a match
{
	//retrieve the "key" group value
	switch (pInnerMatch.Result("${key}").ToUpper())
	{
		case "D":
			// use the "pattern" group value to format today's date
			myValue = myValue.Replace(pMatch.Value,
					DateTime.Now.ToString(pInnerMatch.Result("${pattern}")));
	}
}

The final result:

My mum say i am a good boy on 29Jan2008

Easy, right? :D Don’t have to mess with indexes, where you need to worry about whether the count starts from 0 or 1. And it is reusable in any language! What if you have more than one patterns? Just declare a collection/array (i am sure you know how) and do the hula-loop! :D

Post a Comment