从.NET regex对象获取命名组子模式

Mat*_*att 5 .net c# regex

假设我有以下正则表达式:

var r = new Regex("Space(?<entry>[0-9]{1,3})");
Run Code Online (Sandbox Code Playgroud)

然后我有字符串:

"Space123"
Run Code Online (Sandbox Code Playgroud)

这是我的计划:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道的是,是否有任何方法可以获得匹配的正则表达式部分?在这种情况下:

(?<entry>[0-9]{1,3})
Run Code Online (Sandbox Code Playgroud)

我无法在对象的任何地方找到它,但人们会认为它是可访问的.

Wik*_*żew 5

您可以利用Regex.ToString()存储正则表达式模式的方法.可以使用Regex.GetGroupNames()和获得命名的捕获组及其各自的索引Regex.GetGroupNumbers().

此外,我们需要正则表达式模式中的捕获组的数组/列表,这就是为什么我添加rxPairedRoundBrackets正则表达式来捕获未转义的圆括号内的所有文本.

我建议使用此代码来获取特定命名组的正则表达式子模式(编辑:现在,甚至处理嵌套的非转义括号组!):

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);
}
Run Code Online (Sandbox Code Playgroud)

以下是您案例的代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

在此输入图像描述