Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count regex replaces (C#)

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.

like image 632
Simon D Avatar asked Feb 14 '11 15:02

Simon D


People also ask

Can I use regex in replace?

The Regex. Replace(String, String, MatchEvaluator, RegexOptions) method is useful for replacing a regular expression match if any of the following conditions is true: If the replacement string cannot readily be specified by a regular expression replacement pattern.

How to use regex in replace C#?

Replace Special Characters from string using Regex in C# If you are having a string with special characters and want's to remove/replace them then you can use regex for that. Use this code: Regex. Replace(your String, @"[^0-9a-zA-Z]+", "")

How do I replace multiple spaces with a single space in C#?

If you need to replace multiple spaces (double spaces) in a string to single space with C# you can use next string method: public string Replace(string oldValue, string newValue)

How do you delete multiple spaces with a single space in a string?

The metacharacter “\s” matches spaces and + indicates the occurrence of the spaces one or more times, therefore, the regular expression \S+ matches all the space characters (single or multiple). Therefore, to replace multiple spaces with a single space.


2 Answers

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.

like image 107
Simon D Avatar answered Oct 26 '22 10:10

Simon D


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";
});
like image 7
Guffa Avatar answered Oct 26 '22 11:10

Guffa