.NET Capture,Group,Match之间的差异

smw*_*dia 6 regex

我正在使用.NET Regex类型进行小型应用程序.而"捕捉,分组和匹配"类型让我很困惑.我从未见过如此丑陋的解决方案.有人可以解释一下他们的用法吗?非常感谢.

Ala*_*ore 12

这是一个比@Dav引用的文档更简单的例子:

string s0 = @"foo%123%456%789";
Regex r0 = new Regex(@"^([a-z]+)(?:%([0-9]+))+$");
Match m0 = r0.Match(s0);
if (m0.Success)
{
  Console.WriteLine(@"full match: {0}", m0.Value);
  Console.WriteLine(@"group #1: {0}", m0.Groups[1].Value);
  Console.WriteLine(@"group #2: {0}", m0.Groups[2].Value);
  Console.WriteLine(@"group #2 captures: {0}, {1}, {2}",
                    m0.Groups[2].Captures[0].Value,
                    m0.Groups[2].Captures[1].Value,
                    m0.Groups[2].Captures[2].Value);
}
Run Code Online (Sandbox Code Playgroud)

结果:

full match: foo%123%456%789
group #1: foo
group #2: 789
group #2 captures: 123, 456, 789

full matchgroup #1结果很简单,但有些则需要一些解释.正如您所见,组#2位于由+量词控制的非捕获组内.它匹配三次,但是如果你要求它Value,你只能得到第三次匹配的东西 - 最后的捕获.同样,如果$2在替换字符串中使用占位符,则最终捕获将插入其位置.

在大多数正则表达口味中,这就是你所能得到的; 每个中间捕获被下一个覆盖并丢失; .NET在保存所有捕获并在执行匹配后使其可用时几乎是唯一的.你可以像我在这里一样直接访问它们,或者CaptureCollection像你一样迭代MatchCollection.但是,对于$1-style替换字符串占位符没有等价物.

所以API设计如此丑陋(正如你所说)的原因有两个:首先它是从Perl对.NET的面向对象框架的整体正则表达式支持中改编而来的; 然后将CaptureCollection结构嫁接到它上面.Perl 6提供了一个更清晰的解决方案,但是作者通过从头开始重写Perl并向后抛出向后兼容性来实现这一点.