Regex looping through matches and replacing each match in C# [duplicate]

Is there a way to count the number of replacements a Regex.Replace call makes?

E.g. for Regex.Replace("aaa", "a", "b"); I want to get the number 3 out (result is "bbb"); for Regex.Replace("aaa", "(?<test>aa?)", "${test}b"); I want to get the number 2 out (result is "aabab").

Ways I can think to do this:

  1. Use a MatchEvaluator that increments a captured variable, doing the replacement manually
  2. Get a MatchCollection and iterate it, doing the replacement manually and keeping a count
  3. Search first and get a MatchCollection, get the count from that, then do a separate replace

Methods 1 and 2 require manual parsing of $ replacements, method 3 requires regex matching the string twice. Is there a better way.


Thanks to both Chevex and Guffa. I started looking for a better way to get the results and found that there is a Result method on the Match class that does the substitution. That's the missing piece of the jigsaw. Example code below:

using System.Text.RegularExpressions;

namespace regexrep
{
    class Program
    {
        static int Main(string[] args)
        {
            string fileText = System.IO.File.ReadAllText(args[0]);
            int matchCount = 0;
            string newText = Regex.Replace(fileText, args[1],
                (match) =>
                {
                    matchCount++;
                    return match.Result(args[2]);
                });
            System.IO.File.WriteAllText(args[0], newText);
            return matchCount;
        }
    }
}

With a file test.txt containing aaa, the command line regexrep test.txt "(?<test>aa?)" ${test}b will set %errorlevel% to 2 and change the text to aabab.


You can use a MatchEvaluator that runs for each replacement, that way you can count how many times it occurs:

int cnt = 0;
string result = Regex.Replace("aaa", "a", m => {
  cnt++;
  return "b";
});

The second case is trickier as you have to produce the same result as the replacement pattern would:

int cnt = 0;
string result = Regex.Replace("aaa", "(?<test>aa?)", m => {
  cnt++;
  return m.Groups["test"] + "b";
});