为什么Regex.Match在结果中包含非捕获组?

时间:2013-10-15 14:35:44

标签: c# .net regex

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

出于某种原因,Regex.Match表现得好像我甚至没有指定一个非捕获组。尝试在立即窗口中运行它:

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

我希望结果是

"a"

但实际上

"3a"

This question建议我查看群组,但结果中只有一个群组,它也是" 3a"。它包含一个Capture,也包含#34; 3a"。

这里发生了什么?正在使用Regex,还是我需要设置一个选项?

3 个答案:

答案 0 :(得分:8)

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

如果您只是在\w之前尝试匹配\d,请改为使用lookbehind断言:

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

答案 1 :(得分:3)

非捕获组意味着它不会成为一个组。匹配字符串包含在结果字符串中。

如果要排除该部分,请使用lookbehind断言等内容。

@"(?<=\d)\w"

答案 2 :(得分:3)

你误解了非捕获团体的目的。

通常,组(由一对括号()定义)表示两件事:

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

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

您已观察到您的Groups属性包含一个项,但这是正确的,因为默认情况下,第一个组始终是完整表达式的捕获。比照在文档中:

  

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


您仍然可以使用群组来实现您想要的效果,方法是将您要捕获的字符串放入群组中:

\d(\w)

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

使用此修改后的表达式,匹配中的Groups属性应包含2个项目:

  1. 完全匹配(\d\w
  2. 只有上述字符串中您似乎感兴趣的部分,与\w
  3. 相匹配