Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex replace: Transform pattern with a custom function

Tags:

c#

regex

replace

Let's say I have some text such as this:

[MyAppTerms.TermName1]. [MyAppTerms.TermName2]. 1- [MyAppTerms.TermNameX] 2- ...

I want to replace every occurrence of [MyAppTerms.Whatever] with the result of ReadTerm( "MyAppTerms.Whatever" ), where ReadTerm is a static function which receives a term name and returns the term text for the current language.

Is this feasible using Regex.Replace? (alternatives are welcome). I'm looking into substitution groups but I'm not sure if I can use functions with them.

like image 799
dario_ramos Avatar asked Dec 16 '22 08:12

dario_ramos


1 Answers

Use the Regex.Replace(String, MatchEvaluator) overload.

static void Main()
{
    string input = "[MyAppTerms.TermName1]. [MyAppTerms.TermName2]. 1- [MyAppTerms.TermNameX] 2";
    Regex regex = new Regex(@"\[MyAppTerms\.([^\]]+)\]");
    string output = regex.Replace(input, new MatchEvaluator(RegexReadTerm));

    Console.WriteLine(output);
}

static string RegexReadTerm(Match m)
{
    // The term name is captured in the first group
    return ReadTerm(m.Groups[1].Value);
}

The pattern \[MyAppTerms\.([^\]]+)\] matches your [MyAppTerms.XXX] tags and captures the XXX in a capture group. This group is then retrieved in your MatchEvaluator delegate and passed to your actual ReadTerm method.

It's even better with lambda expressions (since C# 3.0):

static void Main()
{
    string input = "[MyAppTerms.TermName1]. [MyAppTerms.TermName2]. 1- [MyAppTerms.TermNameX] 2";
    Regex regex = new Regex(@"\[MyAppTerms\.([^\]]+)\]");
    string output = regex.Replace(input, m => ReadTerm(m.Groups[1].Value));

    Console.WriteLine(output);
}

Here, you define the evaluator straight inside the code which uses it (keeping logically connected pieces of code together) while the compiler takes care of constructing that MatchEvaluator delegate.

like image 151
Mattias Buelens Avatar answered Dec 17 '22 22:12

Mattias Buelens