1

在匹配正则表达式时,我想从结果中排除非捕获组。我错误地认为默认情况下它们会被排除在外,因为它们被称为非捕获组。

但是,出于某种原因,Regex.Match 的行为就好像我什至没有指定非捕获组一样。尝试在立即窗口中运行它:

System.Text.RegularExpressions.Regex.Match("b3a",@"(?:\d)\w").Value

我预计结果是

"a"

但实际上

"3a"

这个问题建议我查看组,但结果中只有一个组,它也是“3a”。它包含一个 Capture,也是“3a”。

这里发生了什么?正则表达式是否被窃听,或者我需要设置一个选项?

4

3 回答 3

8

匹配与捕获不同。(?:\d)只是意味着匹配包含 的子模式\d,但不要费心将其放入捕获组中。您的整个模式(?:\d)\w寻找 a(?:\d)后跟 a \w; 它在功能上等同于\d\w.

如果您\w仅在 a 前面有 a 时尝试匹配它\d,请改用后向断言:

System.Text.RegularExpressions.Regex.Match("b3a", @"(?<=\d)\w").Value
于 2013-10-15T14:39:39.250 回答
3

非捕获组意味着它不创建组。匹配的字符串包含在结果字符串中。

如果要排除该部分,请使用诸如后向断言之类的东西。

@"(?<=\d)\w"
于 2013-10-15T14:39:09.653 回答
3

您误解了非捕获组的目的。

一般来说,组(由一对括号定义())意味着两件事:

  • 包含的正则表达式是分组的,因此括号后的任何量词都适用于整个表达式,而不仅仅是前一个字符。
  • 与组匹配的子字符串作为子捕获存储在Groups属性中。

有时,您不希望某些组的第二个结果,这就是引入非捕获组的原因:它们允许您对子表达式进行分组,而无需将任何匹配项存储在Groups属性的项目中。

不过,您已经观察到您的Groups属性包含一个项目 - 这是真的,因为默认情况下,第一组始终是完整表达式的捕获。参看。在文档中:

如果正则表达式引擎可以找到匹配项,则 Groups 属性返回的 GroupCollection 对象的第一个元素包含与整个正则表达式模式匹配的字符串。


通过将要捕获的字符串放入组中,您仍然可以使用组来实现您想要的:

\d(\w)

(我再次省略了非捕获组,因为它不会改变您上述表达式中的任何内容。)

使用这个修改后的表达式,Groups匹配中的属性应该有 2 项:

  1. 完全匹配(的\d\w
  2. 只有您似乎感兴趣的上述字符串的一部分,匹配\w
于 2013-10-15T14:40:14.600 回答