【问题标题】:Differences among .NET Capture, Group, Match.NET Capture、Group、Match 之间的差异
【发布时间】:2011-01-16 01:25:16
【问题描述】:

我正在使用 .NET Regex 类型制作一个小应用程序。而“捕获、分组和匹配”类型完全让我感到困惑。我从未见过如此丑陋的解决方案。有人可以为我解释一下它们的用法吗?非常感谢。

【问题讨论】:

  • 你有一个正则表达式的例子想让我们解释一下吗?

标签: regex


【解决方案1】:

这是一个比@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 在保留所有捕获并在执行匹配后使它们可用方面几乎是独一无二的。您可以像我在这里所做的那样直接访问它们,或者像 MatchCollection 一样遍历 CaptureCollection。不过,$1 样式的替换字符串占位符没有等价物。

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

【讨论】:

  • 嗨,谢谢艾伦。还有两个问题,Match 和 Group 都有一个名为“Captures”的属性,Match.Captures 和 Group.Captures 有什么区别?为什么 Match.Groups[0] 总是与 Match.Value 相同?再次感谢。
  • A Match ISA Group ISA Capture,因此 Match 从 Group 继承 Captures,从 Capture 继承 Value。匹配是第零组,所以Match.Captures 只是一个包含整个匹配的单元素列表——好像我们需要另一种 方式来引用它! Value 显然是首选方式,它更短更直观。但是,如果您使用期望字符串的 Match/Group/Capture 引用,即使这也是可选的,因为 ToString() 只是委托给 Value
  • 至于为什么匹配是第零组,请看这个答案:stackoverflow.com/questions/2248213/…
  • 谢谢,艾伦。我会阅读链接。当我明白时我会告诉你的。 =8^D
  • 嗨,艾伦,我已经阅读了您提供的链接。尽管还有许多其他解释,但我同意您的观点,即 Match.Group[0] 用于整个比赛,因为 RegEx 捕获是基于 1 的。这正是我所假设的。干杯!
【解决方案2】:

匹配是正则表达式整个的任何单独匹配的结果。组和捕获都与捕获组有关(每个 (expression) 来自正则表达式),但它们的行为方式有所不同。下面是 MSDN 文章中关于 Capture 类的一段引述,它解释了不同之处:

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

(Source)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多