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