Summary: in this tutorial, you will learn about capturing groups and how to use the C# Regex Groups property to get the matches.
Introduction to the C# Regex Groups
Suppose you want to match a route that starts with posts
followed by a forward slash /
and an id
like this:
posts/id
Code language: C# (cs)
To do that, you may come up with the following regular expression pattern:
posts/\d+
And the following program illustrates how you would use that pattern to match the route:
using System.Text.RegularExpressions;
using static System.Console;
var route = "posts/100";
var pattern = @"posts/\d+";
var match = Regex.Match(route, pattern);
WriteLine(match.Value);
Code language: C# (cs)
Output:
posts/100
Code language: C# (cs)
The pattern posts/\d+
matches the posts/
characters and is followed by one or more digits. It returns the result as expected.
Now, you want to extract the id from the route, which is 100 in this case. To do that, you can use something called capturing group in regular expressions.
By definition, a capturing group allows you to capture a portion of the matched text. To create a capturing group, you define a subpattern within the overall pattern and closed it within parentheses.
In our example, we can create a subpattern like this:
posts/(\d+)
Code language: C# (cs)
This (\d+)
is a capturing group and \d+
is a subpattern.
If the matches are found, you can access the groups via the Groups
property of the Match
object. The type of Groups
is the GroupCollection
type which is a collection of Group
objects.
The first element in the Groups
collection is the whole match which is posts/100
in this example and the next elements are the matched text of the capturing groups.
The following example uses the capturing group to exact the id
from the route posts/100
:
using System.Text.RegularExpressions;
using static System.Console;
var route = "posts/100";
var pattern = @"posts/(\d+)";
var match = Regex.Match(route, pattern);
if (match.Success)
{
foreach (var group in match.Groups)
{
WriteLine(group);
}
}
Code language: C# (cs)
Output:
posts/100
100
Code language: C# (cs)
A regular expression may contain multiple capturing groups. For example:
using System.Text.RegularExpressions;
using static System.Console;
// posts/year/month/date format
var route = "posts/2023/12/31";
var pattern = @"posts/(\d{4})/(\d{2})/(\d{2})";
var match = Regex.Match(route, pattern);
if (match.Success)
{
foreach (var group in match.Groups)
{
WriteLine(group);
}
}
Code language: C# (cs)
Output:
posts/2023/12/31
2023
12
31
Code language: C# (cs)
In this example, we have three capturing groups for year, month, and date in the route. The output shows four groups, which include the whole match.
Named capturing groups
By using the Groups
property, you can iterate the groups or access a group by index. For example, the Groups[1]
should return the year which is 2023
:
using System;
using System.Text.RegularExpressions;
using static System.Console;
// posts/year/month/date format
var route = "posts/2023/12/31";
var pattern = @"posts/(\d{4})/(\d{2})/(\d{2})";
var match = Regex.Match(route, pattern);
if (match.Success && match.Groups.Count == 4)
{
var year = match.Groups[1];
var month = match.Groups[2];
var day = match.Groups[3];
WriteLine($"{year}/{month}/{day}");
}
Code language: JavaScript (javascript)
It’s more explicit to assign a name to each capturing in the regular expression so that we can access each group by name rather than by index.
To do that, you can use the following syntax:
(?<name>rule)
Code language: C# (cs)
In this syntax:
- The
()
denotes a capturing group. - The
?<name>
specifies the capturing group’s name. - The
rule
is a subpattern.
To access the matched value, you look it up in the Groups
property by group name like this:
Groups["name"]
Code language: C# (cs)
For example:
using System.Text.RegularExpressions;
using static System.Console;
// posts/year/month/date format
var route = "posts/2023/12/31";
var pattern = @"posts/(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})";
var match = Regex.Match(route, pattern);
if (match.Success)
{
var year = match.Groups["year"];
var month = match.Groups["month"];
var day = match.Groups["day"];
WriteLine($"{year}/{month}/{day}");
}
Code language: C# (cs)
Output:
2023/12/31
Code language: C# (cs)
Summary
- Place a pattern inside the parentheses
()
to create a capturing group. - Use the
Match.Groups
property to access the groups. The first group is the whole match and the next ones are the matched groups. - Use the
(?<name>rule)
syntax to assign aname
to a capturing group and access its matched value usingGroups["name"]
.