Regex 101 Exercise I9 - Count the number of matches

Given a string like:

# # 4 6 # # 7 # 45 # 43 # 65 56 2 # 4345 # # 23

 

Count how many numbers there are in this string

-----

There are a few ways to approach this problem.

In all of them, we need a way to capture the numeric parts of the string. We've done that before, using something like:

\d+

We can then apply that repeatedly, with code that looks something like this:

Regex regex = new Regex("\d+");

Match match = regex.Match(inputString);
int count = 0;

while (match.Success)
{
   count++;
   match = match.NextMatch();

}

That's a bit ugly, however. There's a shortcut, however, using:

MatchCollection matches = regex.Matches(inputString);
int count = matches.Count;

That gives the same result.

There's another, more "advanced" approach we can use. The regex is more complex, and the code that you write is harder to understand, so I probably wouldn't prefer it over the last approach.

To use it, you need to know a new piece of information about the Match class (where "new" means "something I haven't talked about").

In earlier examples, we used the "Groups" indexer to pull out values that we had captured. So, if we wrote something like:

(?<Digits>\d+)

We would use:

match.Groups["Digits"].Value

to get the string.

It is possible to write a regex in which a given capture is used more that one time, and therefore corresponds to multiple strings. If we write:

(               # Start up repeating section
  (?<Digits>\d+)  # a sequence of digits

  (\D+|$)         # not digits or end

)+              # repeat match

 

We have a single regex that will match a repeating series of digits follow by non-digits, and each match is stored using the "Digits" capture.

To get at these captures, we use:

match.Captures["Digits"]

which is a collection of captures, with each one containing the value from one of the captures. To solve our problem, we'd be interested in the length, which is:

match.Captures["Digits"].Length

 

If you want extra credit, you can also do this by using Regex.Split(), though I've found that Regex.Match() is easier to use for this sort of problem.