Regex replace: Transform pattern with a custom fun

2019-06-25 04:29发布

问题:

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.

回答1:

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.



标签: c# regex replace