【问题标题】:Why does Regex.Match include noncapturing groups in the result?为什么 Regex.Match 在结果中包含非捕获组?
【发布时间】:2013-10-15 22:46:51
【问题描述】:

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

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

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

我希望结果是

"a"

其实是这样的

"3a"

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

这里发生了什么?正则表达式是否存在问题,或者我需要设置一个选项?

【问题讨论】:

    标签: c# .net regex


    【解决方案1】:

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

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

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

    【讨论】:

    • @"\d(\w)" 并根据需要使用组。我发现它更容易阅读(虽然它可能会更慢,不知道)
    【解决方案2】:

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

    如果要排除该部分,请使用lookbehind assertion之类的东西。

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

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


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

      \d(\w)
      

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

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

      1. 完整匹配(\d\w
      2. 仅上面字符串中您似乎感兴趣的部分,与\w 匹配

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-25
        • 2019-03-08
        • 2019-07-26
        • 1970-01-01
        • 2014-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多