在匹配正则表达式时,我想从结果中排除noncapturing groups。我错误地认为他们默认被排除在外,因为他们被称为非捕获组。
出于某种原因,Regex.Match表现得好像我甚至没有指定一个非捕获组。尝试在立即窗口中运行它:
System.Text.RegularExpressions.Regex.Match("b3a",@"(?:\d)\w").Value
我希望结果是
"a"
但实际上
"3a"
This question建议我查看群组,但结果中只有一个群组,它也是" 3a"。它包含一个Capture,也包含#34; 3a"。
这里发生了什么?正在使用Regex,还是我需要设置一个选项?
答案 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个项目:
\d\w
)\w