3

I want to count the number of times a regular expression is matched in a string using C#. I have used this site to help validate my regular expression: http://regexpal.com/

My regular expression is:

Time(\\tChannel [0-9]* \(mV\))*

And here is the input string:

Time\tChannel 1 (mV)\tChannel 2 (mV)\tChannel 3 (mV)\tChannel 4 (mV)\tChannel 5 (mV)\tChannel 6 (mV)\tChannel 7 (mV)\tChannel 8 (mV)\tChannel 1_cal (mg/L)\tChannel 2_cal ()\tChannel 3_cal ()\tChannel 4_cal ()\tChannel 5_cal ()\tChannel 6_cal ()\tChannel 7_cal ()\tChannel 8_cal ()\tMotor 1 (mm)\tMotor 2 (mm)

My expectation is that for my input string my regular expression should yield 8 matches. But I can't seem to find a way to compute that number. Can anybody help?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Diemauerdk
  • 5,238
  • 9
  • 40
  • 56
  • This question should not have been closed as a duplicate. This question asks about counting the number of times that a *pattern* appears in a string, whereas the [referenced question](http://stackoverflow.com/questions/3016522) asks about counting a *fixed string*. – DavidRR May 05 '16 at 15:52

2 Answers2

3

For this particular scenario, you could do something like this:

Regex.Match(input, pattern).Groups[1].Captures.Count

The element in Groups[0] would be the entire match, so that's not helpful for what you need. Groups[1] will contain the entire (\\tChannel [0-9]* \(mV\))* section, which includes all the repeats. To get the number of times it repeates you use .Captures.Count

Sample based on your example:

Regex.Match(
    @"Time\tChannel 1 (mV)\tChannel 2 (mV)\tChannel 3 (mV)\tChannel 4 (mV)\tChannel 5 (mV)\tChannel 6 (mV)\tChannel 7 (mV)\tChannel 8 (mV)\tChannel 1_cal (mg/L)\tChannel 2_cal ()\tChannel 3_cal ()\tChannel 4_cal ()\tChannel 5_cal ()\tChannel 6_cal ()\tChannel 7_cal ()\tChannel 8_cal ()\tMotor 1 (mm)\tMotor 2 (mm)", 
    @"Time(\\tChannel [0-9]* \(mV\))*"
).Groups[1].Captures.Count;

I apologize for the poor formatting there, but this should show you how this can be done at the very least.

The examples given around Regex.Matches(...).Count won't work here because it's a single match. You can't just use Regex.Match(...).Groups.Count either because you only have one group specified, which leaves this with 2 groups returned from the match. You need to look at your specific group Regex.Match(...).Groups[1] and get the count from the number of captures in that group.

Also, you can name the groups which might make it a little bit clearer on what is happening. Here's an example:

Regex.Match(
    @"Time\tChannel 1 (mV)\tChannel 2 (mV)\tChannel 3 (mV)\tChannel 4 (mV)\tChannel 5 (mV)\tChannel 6 (mV)\tChannel 7 (mV)\tChannel 8 (mV)\tChannel 1_cal (mg/L)\tChannel 2_cal ()\tChannel 3_cal ()\tChannel 4_cal ()\tChannel 5_cal ()\tChannel 6_cal ()\tChannel 7_cal ()\tChannel 8_cal ()\tMotor 1 (mm)\tMotor 2 (mm)", 
    @"Time(?<channelGroup>\\tChannel [0-9]* \(mV\))*"
).Groups["channelGroup"].Captures.Count;
Terry
  • 895
  • 7
  • 20
2

Instead of Regex.Match, use Regex.Matches:

Regex.Matches(input, pattern).Cast<Match>().Count();

As a rule, I generally cast the MatchCollection returned by Matches to IEnumerable<Match> so it plays nice with linq. You might just prefer:

Regex.Matches(input, pattern).Count;
spender
  • 117,338
  • 33
  • 229
  • 351