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

时间:2010-02-12 07:57:49

标签: regex

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

2 个答案:

答案 0 :(得分: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);
}

结果:

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 - 样式替换字符串占位符没有等价物。

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

答案 1 :(得分:2)

匹配是正则表达式的完整的任何单独匹配的结果。组和捕获都与捕获组(正则表达式中的每个(expression))有关,但它们的行为方式不同。以下是有关Capture类的MSDN文章的引用,该文章解释了差异:

  

如果你没有将量词应用于   捕获组,Group.Captures   property返回一个CaptureCollection   用一个Capture对象   提供有关相同的信息   捕获为Group对象。如果你这样做   将量词应用于捕获   group,Group.Index,Group.Length,   和Group.Value属性提供   关于最后一个的信息   捕获组,而捕获组   CaptureCollection中的对象   提供所有信息   子表达式捕获。这个例子   提供了一个例证。

     

Source