Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use perl-style replacement expressions in .NET

Tags:

c#

.net

regex

I am building a .NET text formatting component which uses a list of configurable regexes to transform input text. I need to allow case conversion using regex rules as well, but I can't seem to figure out how to do this in .NET. A perl-style replacement expression such as s/(\b)([a-z])/\1\u\2/g would do the trick, but .NET doesn't seem to support it. I know I can use MatchEvaluator with a delegate, but I need my replacement rules to be configurable (text).

Any help would be appreciated.

like image 304
remy Avatar asked Nov 28 '25 16:11

remy


1 Answers

The most .NET-style way would be

 var regex = new Regex(@"^(?<first>.*?):(?<second>.*)$", RegexOptions.Compiled);
 Console.WriteLine(regex.Replace("moon:glow", "${second}:${first}"));

Will print

 glow:moon

You can also use ordinal references, like so:

 Console.WriteLine(regex.Replace("moon:glow", "$2:$1"));

Mixing them is ok.

In contrast to Perl you can individually retrieve all matched values for repeated atoms, like e.g.:

var regex = new Regex(@"^((?<token>.*?):)*", RegexOptions.Compiled);
foreach (Capture token in regex
         .Match("moon:glow:is:the most:beautiful:thing")
         .Groups["token"].Captures)
     Console.WriteLine(token.Value);

Output

moon
glow
is
the most
beautiful

To get sophisticated match evaluation, you'd do e.g.

var upper = Regex.Replace("moon:glow:is:the most:beautiful:thing", "(.*?)(:|$)",                  
    m => m.Groups[1].Value.ToUpper() + m.Groups[2]);
Console.WriteLine(upper);

Unfortunately, I see no easy way to configure such a evaluation function as text only (except when using Compiler as a service, which I know is available on Mono, but I'm not quite sure on MS .Net yet)

like image 173
sehe Avatar answered Dec 01 '25 06:12

sehe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!