Reputation: 26971
Let's say I have the following regex:
var r = new Regex("Space(?<entry>[0-9]{1,3})");
Then I have the string:
"Space123"
Here is my program:
void Main()
{
Regex r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture);
foreach (Match m in r.Matches("Space123")){
m.Groups["entry"].Dump(); //Dump() is linqpad to echo the object to console
}
}
What I want to know is if there is any way to to get the regular expression part that matched? In this case:
(?<entry>[0-9]{1,3})
I can't find it anywhere in the object, but one would think it would be accessible.
Upvotes: 5
Views: 370
Reputation: 626709
You can leverage the Regex.ToString()
method that stores the regular expression pattern. Named capure groups and their respective indices can be obtained using Regex.GetGroupNames()
and Regex.GetGroupNumbers()
.
Also, we need an array/list of the capture groups inside the regex pattern, that is why I am adding rxPairedRoundBrackets
regex to capture all texts inside unescaped round brackets.
I suggest this code to get the regex subpattern for a specific named group (edit: now, even handling nested unescaped parenthetical groups!):
var rxPairedRoundBrackets = new Regex(@"(?sx)(?=((?<=[^\\]|^)\(
(?>
(?! (?<!\\)\( | (?<!\\)\) ) .
|
(?<!\\)\( (?<Depth>)
|
(?<!\\)\) (?<-Depth>)
)*
(?(Depth)(?!))
(?<!\\)\)))+");
var r = new Regex(@"(?<OuterSpace>Spa(?<ce>ce))(?<entry>\([0-9]{1,3}\))", RegexOptions.ExplicitCapture);
var bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value);
var GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i })
.ToDictionary(item => item.s, item => item.i);
foreach (Match m in r.Matches("My New Space(123)"))
{
var id = "entry";
var grp = m.Groups[id]; // Just to see the group value
var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1);
}
And here is the code for your case:
r = new Regex("Space(?<entry>[0-9]{1,3})", RegexOptions.ExplicitCapture);
bracketedGrps = rxPairedRoundBrackets.Matches(r.ToString()).Cast<Match>().Select(p => p.Groups[1].Value);
GroupDict = r.GetGroupNames().Zip(r.GetGroupNumbers(), (s, i) => new { s, i })
.ToDictionary(item => item.s, item => item.i);
foreach (Match m in r.Matches("Space123"))
{
var id = "entry";
var grp = m.Groups[id];
var groupThatMatched = bracketedGrps.ElementAt(GroupDict[id] - 1);
}
Output:
Upvotes: 5