首页 > 解决方案 > 名称不被视为编号组的正则表达式组

问题描述

谁能解释正则表达式的命名组有时像未命名组一样编号而有时没有编号的行为。

例如:

var text = "The big brown fox jumped over the lazy dog.";

var pat1 = @"(?<sentence>(\w+(\s+|\.))+)";
var re1 = new Regex(pat1);
var m1 = re1.Match(text);
Console.WriteLine($"m1.Groups[\"sentence\"].Value: {m1.Groups["sentence"].Value}");
Console.WriteLine($"         m1.Groups[0].Value: {m1.Groups[0].Value}");
Console.WriteLine($"         m1.Groups[1].Value: {m1.Groups[1].Value}");
Console.WriteLine($"         m1.Groups[2].Value: {m1.Groups[2].Value}");
Console.WriteLine($"         m1.Groups[3].Value: {m1.Groups[3].Value}");
Console.WriteLine($"         m1.Groups[4].Value: {m1.Groups[4].Value}");
Console.WriteLine();

// pat2 is the same as pat1 but without the name for the first group
var pat2 = @"((\w+(\s+|\.))+)";
var re2 = new Regex(pat2);
var m2 = re2.Match(text);
Console.WriteLine($"m2.Groups[0].Value: {m2.Groups[0].Value}");
Console.WriteLine($"m2.Groups[1].Value: {m2.Groups[1].Value}");
Console.WriteLine($"m2.Groups[2].Value: {m2.Groups[2].Value}");
Console.WriteLine($"m2.Groups[3].Value: {m2.Groups[3].Value}");
Console.WriteLine($"m2.Groups[4].Value: {m2.Groups[4].Value}");
Console.WriteLine();

var pat3 = @"The\s+(?<word>\w+)\s+brown.*$";
var re3 = new Regex(pat3);
var m3 = re3.Match(text);
Console.WriteLine($"m3.Groups[\"word\"].Value: {m3.Groups["word"].Value}");
Console.WriteLine($"     m3.Groups[0].Value: {m3.Groups[0].Value}");
Console.WriteLine($"     m3.Groups[1].Value: {m3.Groups[1].Value}");
Console.WriteLine($"     m3.Groups[2].Value: {m3.Groups[2].Value}");
Console.WriteLine();

承担以下结果:

m1.Groups["sentence"].Value: The big brown fox jumped over the lazy dog.
         m1.Groups[0].Value: The big brown fox jumped over the lazy dog.
         m1.Groups[1].Value: dog.
         m1.Groups[2].Value: .
         m1.Groups[3].Value: The big brown fox jumped over the lazy dog.
         m1.Groups[4].Value: 

m2.Groups[0].Value: The big brown fox jumped over the lazy dog.
m2.Groups[1].Value: The big brown fox jumped over the lazy dog.
m2.Groups[2].Value: dog.
m2.Groups[3].Value: .
m2.Groups[4].Value: 

m3.Groups["word"].Value: big
     m3.Groups[0].Value: The big brown fox jumped over the lazy dog.
     m3.Groups[1].Value: big
     m3.Groups[2].Value: 

我希望m1.Groups[1].Value == m2.Groups[1].Value的结果与m1.Groups[2].Valuem1.Groups[3].Value我希望它们匹配m2 .Groups[2].Valuem2.Groups[3].Value分别。

正则表达式评估器的行为就像如果组被命名(因为它在pat1中,它被命名为“sentence”),那么它不会像m1.Groups[1].Value那样参与计数,然后 RE 评估器产生一个意外的m1.Groups[3].Valuem1.Groups[0].Value或我预期的m1.Groups[1].Value相同。

现在,如果命名组不参与组计数,则第三个模式 pat3(具有命名组:“word”)的行为与我预期的一样。命名组与否,第一组括号房屋组 1,第二组括号房屋组 2,等等。

我找不到任何解释这种行为的文献。您的帮助将不胜感激。

标签: c#regex

解决方案


@WiktorStribiżew 感谢您的参考。

答案是:首先捕获未命名的组,然后是命名的组。

因此,m1.Groups[1].Value捕获第一个未命名的括号组(\w+(\s+|\.))m1.Groups[2].Value捕获第二个未命名的括号组,(\s+|\.)最后m1.Group[3].Value捕获第一个命名的括号组,(?<sentence>(\w+(\s+|\.))+).


推荐阅读