RegEx MatchEvaluator, how to write a oneliner?

I'm working off the help here for examples and struggliong to understand how I can convert it's multiline example into a oneliner. I'm more used to Perl ;-).

Here's some code fro example that works:

string First3(Match M) { return M.Value.Remove(3); } // defined in the class MyClass

MyClass C = new MyClass(); // A class which has a method called First3

MatchEvaluator ME = new MatchEvaluator(C.First3);

string S = Regex.Replace(sMonths, "(January|February|March|April|May|June|July|August|September|October|November|December)", ME);

Now I want to avoid instantiating MyClass. I'm aiming at something more like this:

string S = Regex.Replace(sMonths, "(January|February|March|April|May|June|July|August|September|October|November|December)", new MatchEvaluator(this.Value.Remove(3)));

in short a one-liner. But the semantics of "this" are escaping me here (i.e. this kind of code fails ;-). and I can't see how to identify the argument to the new MatchEvaluator to give it an implicit function return as I'm aiming to achieve.

Am I barking up the wrong tree, is this possible?

If there's an easier way to convert long month names to short I'm open to hearing that too, but all the same I'd like to nuderstand the semantics of MatchEvaluators here and how to write oneliners! That is, I want to solve this particular problem and I want to understand the general case of MatchEvaluators.

Cheers,

Bernd.

(Moderator: Thread moved to the Regular Expression Forum)
[1901 byte] By [BerndWechner] at [2008-2-24]
# 1
I am not sure what the goal of the code is...but here is an example to do a replacement using Regex



string text = "blah blah<br>";
string regex = "<br>";
string replacement = "<br/>";

string result = Regex.Replace(text, regex, replacement, RegexOptions.IgnoreCase);

Its one line in that you can call the static function of Replace, instead of instantiating the class.

OmegaMan at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...
# 2
Bernd Wechner wrote:

If there's an easier way to convert long month names to short I'm open to hearing that too...

You may want to look into DateTime.ParseExact, I needed to extract a month number from a string month



public static int GetMonthNumber( string Month )
{
return DateTime.ParseExact(Month.Substring(0, 3), "MMM", System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat).Month;
}

I don't know if you have to deal with culture specific dates, but that could handle it. Basically the user passed in a month as a string and the above code returned the integer. One could take the month number and rework as shown below:


string Month = "January";

int iMonth = DateTime.ParseExact(Month.Substring(0, 3), "MMM", System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat).Month;

Console.WriteLine((new DateTime(2005, iMonth, 1)).ToString("MMM")); // Output JAN

OmegaMan at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...
# 3
OmegaMan wrote:
I am not sure what the goal of the code is...but here is an example to do a replacement using Regex



string text = "blah blah<br>";
string regex = "<br>";
string replacement = "<br/>";

string result = Regex.Replace(text, regex, replacement, RegexOptions.IgnoreCase);

Its one line in that you can call the static function of Replace, instead of instantiating the class.

Instead of replacing by "replacement" use a MatchEvaluator to run a function of your own design on the matched text and return what you want it to become. That's the variant I'm exploring. Static string replacement works as a one liner, but it's the semantics of passing a a MatchEvaluator to the the Replace method that escape me.

BerndWechner at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...
# 4

Actually what I'm after is to convert all occurences of January to Jan, February to Feb and so on. The working version of a RegEx with a MatchEvaluator object does this by discarding all but the first three characters of matched strings. Even with DateTime parsing methods the easiest way to process a long complex string which includes many things and some possible dates in one line of code is with a RegEx that does a replace in such a way (or perhaps not).

But aside from that goal, I really want to understand more about how to pass MatchEvaluator functions to the RegEx.Replace method!

Here for the record is a two-liner that works:

public static string First3(Match M) { return M.Value.Remove(3); }

private string MonthShrink(string S) { return Regex.Replace(S, @"(January|February|March|April|May|June|July|August|September|October|November|December)", new MatchEvaluator(ThisClass.First3)); }

Can I get this down to one line? The problem is that Remove is a method of the class string and Value is a property of the class Match and I can't find a syntax to do this operation in-line on the MonthShrink methods declaration. It must be possible, or?

BerndWechner at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...
# 5
Bernd Wechner wrote:
Instead of replacing by "replacement" use a MatchEvaluator to run a function of your own design on the matched text and return what you want it to become. That's the variant I'm exploring. Static string replacement works as a one liner, but it's the semantics of passing a a MatchEvaluator to the the Replace method that escape me.
Sorry Bernd I keep throwing code at you....If I finally get the gist, is that you don't want to have to instantiate the class to use the delegate. In that case one could use an inplace delegate. I have taken MSDNs example and used an inplace delegate. I hope this is what you are looking for:


static void Main(string[] args)

{

string sInput, sRegex;

// The string to search.

sInput = "aabbccddeeffcccgghhcccciijjcccckkcc";

// A very simple regular expression.

sRegex = "cc";

Regex r = new Regex(sRegex);

MatchEvaluator replaceCC = delegate(Match m)

{

i++;

return i.ToString() + i.ToString();

};
// Assign the replace method to the MatchEvaluator delegate.

MatchEvaluator myEvaluator = new MatchEvaluator(replaceCC);

// Write out the original string.

Console.WriteLine(sInput);

// Replace matched characters using the delegate method.

sInput = r.Replace(sInput, myEvaluator);

// Write out the modified string.

Console.WriteLine(sInput);

}

public static int i=0;


OmegaMan at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...
# 6

Is this a oneline replacement you are looking for? I decided to match what is wanted and to use the ignore match to strip what is not. Instead of trying to shoehorn a replacement.

Here is the code


string text =
@"January
February
March
April
May
June
July
August
September
October
November
December";
string pattern =
@"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(?:r?uary|ch|il|ember|e|y|ust|tember|ober|$)";

string replace = "$1";
Console.WriteLine(
Regex.Replace(text, pattern, replace, RegexOptions.Multiline | RegexOptions.Singleline));

Console OutputJan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
OmegaMan at 2007-9-3 > top of Msdn Tech,.NET Development,Regular Expressions...

.NET Development

Site Classified