'How do I get the name of captured groups in a C# Regex?
Is there a way to get the name of a captured group in C#?
string line = "No.123456789 04/09/2009 999";
Regex regex = new Regex(@"(?<number>[\d]{9}) (?<date>[\d]{2}/[\d]{2}/[\d]{4}) (?<code>.*)");
GroupCollection groups = regex.Match(line).Groups;
foreach (Group group in groups)
{
Console.WriteLine("Group: {0}, Value: {1}", ???, group.Value);
}
I want to get this result:
Group: [I don´t know what should go here], Value: 123456789 04/09/2009 999 Group: number, Value: 123456789 Group: date, Value: 04/09/2009 Group: code, Value: 999
Solution 1:[1]
Use GetGroupNames to get the list of groups in an expression and then iterate over those, using the names as keys into the groups collection.
For example,
GroupCollection groups = regex.Match(line).Groups;
foreach (string groupName in regex.GetGroupNames())
{
Console.WriteLine(
"Group: {0}, Value: {1}",
groupName,
groups[groupName].Value);
}
Solution 2:[2]
The cleanest way to do this is by using this extension method:
public static class MyExtensionMethods
{
public static Dictionary<string, string> MatchNamedCaptures(this Regex regex, string input)
{
var namedCaptureDictionary = new Dictionary<string, string>();
GroupCollection groups = regex.Match(input).Groups;
string [] groupNames = regex.GetGroupNames();
foreach (string groupName in groupNames)
if (groups[groupName].Captures.Count > 0)
namedCaptureDictionary.Add(groupName,groups[groupName].Value);
return namedCaptureDictionary;
}
}
Once this extension method is in place, you can get names and values like this:
var regex = new Regex(@"(?<year>[\d]+)\|(?<month>[\d]+)\|(?<day>[\d]+)");
var namedCaptures = regex.MatchNamedCaptures(wikiDate);
string s = "";
foreach (var item in namedCaptures)
{
s += item.Key + ": " + item.Value + "\r\n";
}
s += namedCaptures["year"];
s += namedCaptures["month"];
s += namedCaptures["day"];
Solution 3:[3]
Since .NET 4.7, there is Group.Name property available.
Solution 4:[4]
You should use GetGroupNames(); and the code will look something like this:
string line = "No.123456789 04/09/2009 999";
Regex regex =
new Regex(@"(?<number>[\d]{9}) (?<date>[\d]{2}/[\d]{2}/[\d]{4}) (?<code>.*)");
GroupCollection groups = regex.Match(line).Groups;
var grpNames = regex.GetGroupNames();
foreach (var grpName in grpNames)
{
Console.WriteLine("Group: {0}, Value: {1}", grpName, groups[grpName].Value);
}
Solution 5:[5]
The Regex class is the key to this!
foreach(Group group in match.Groups)
{
Console.WriteLine("Group: {0}, Value: {1}", regex.GroupNameFromNumber(group.Index), group.Value);
}
Solution 6:[6]
To update the existing extension method answer by @whitneyland with one that can handle multiple matches:
public static List<Dictionary<string, string>> MatchNamedCaptures(this Regex regex, string input)
{
var namedCaptureList = new List<Dictionary<string, string>>();
var match = regex.Match(input);
do
{
Dictionary<string, string> namedCaptureDictionary = new Dictionary<string, string>();
GroupCollection groups = match.Groups;
string[] groupNames = regex.GetGroupNames();
foreach (string groupName in groupNames)
{
if (groups[groupName].Captures.Count > 0)
namedCaptureDictionary.Add(groupName, groups[groupName].Value);
}
namedCaptureList.Add(namedCaptureDictionary);
match = match.NextMatch();
}
while (match!=null && match.Success);
return namedCaptureList;
}
Usage:
Regex pickoutInfo = new Regex(@"(?<key>[^=;,]+)=(?<val>[^;,]+(,\d+)?)", RegexOptions.ExplicitCapture);
var matches = pickoutInfo.MatchNamedCaptures(_context.Database.GetConnectionString());
string server = matches.Single( a => a["key"]=="Server")["val"];
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | Jozef Benikovský |
| Solution 4 | Eran Betzalel |
| Solution 5 | Joel |
| Solution 6 | Kinetic |
