我正在使用.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 match和group #1结果很简单,但有些则需要一些解释.正如您所见,组#2位于由+量词控制的非捕获组内.它匹配三次,但是如果你要求它Value,你只能得到第三次匹配的东西 - 最后的捕获.同样,如果$2在替换字符串中使用占位符,则最终捕获将插入其位置.
在大多数正则表达口味中,这就是你所能得到的; 每个中间捕获被下一个覆盖并丢失; .NET在保存所有捕获并在执行匹配后使其可用时几乎是唯一的.你可以像我在这里一样直接访问它们,或者CaptureCollection像你一样迭代MatchCollection.但是,对于$1-style替换字符串占位符没有等价物.
所以API设计如此丑陋(正如你所说)的原因有两个:首先它是从Perl对.NET的面向对象框架的整体正则表达式支持中改编而来的; 然后将CaptureCollection结构嫁接到它上面.Perl 6提供了一个更清晰的解决方案,但是作者通过从头开始重写Perl并向后抛出向后兼容性来实现这一点.