4

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 Answer 1

15

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This is a perfect case where a lambda expression gives slightly neater code, IMHO. regex.Replace(input, match => ReadTerm(match));
@Mels Very good point, although you probably want to pass only m.Groups[1].Value to ReadTerm instead of the whole Match. Answer updated.
You don't even need that syntax for the lambda. if the function takes one parameter, then you can do this: regex.Replace(input, ReadTerm);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.