如何编写一个可以忽略嵌套捕获的正则表达式?

时间:2014-01-22 18:50:24

标签: c# regex

我正在尝试编写一个带有这些的正则表达式:

 class bob
 {
       ...
 }

 class joe
 {
       {
            ...
       }
 }

 class tim
 {
       {
            ...
       }
       {
            ...
       }
 }

输出(为简单起见减少了空白区域)

 [0]bob
 [1] ... 

 [0]joe
 [1] { ... }

 [0]tim
 [1] { ... } { ... }

我已经尝试class[\s]+([\w]+)[\s]*{([^}]*)}但是(可以理解)停在第一个'}'。

我也试过class[\s]+([\w]+)[\s]*{(.*)}但是贪婪地抓住了所有东西直到最后'}'。

目前,我不在乎外括号内的内容 - 只是我抓住了所有内容。

作为一个额外的“有趣”,我宁愿不依赖于新的行(或类[\ s]之外的任何特定空格 - 所以类bob {}类joe {}会[理论上]是一个有效的输入字符串)。

不,我没有制作一个完整的或真正的标记器/解析器,只是我自己的代码可视化器(如果我完成了这个副项目 - 那就是)。

2 个答案:

答案 0 :(得分:2)

您可以使用平衡组:

class\s*([^{]+?)\s*\{(  # Match the class and the first '{'
    (?:                 
        [^{}]           # Match all non-braces
        |
        (?<open>\{)     # Match '{', and capture into 'open'
        |
        (?<-open>\})    # Match '}', and delete the 'open' capture
    )+
    (?(open)(?!))       # Fails if 'open' stack isn't empty
)\}

如果您输入评论和缩进,请务必使用RegexOptions.IgnoreWhitespace标记。

答案 1 :(得分:0)

严格来说,正则表达式无法处理递归。因此,您不能编写一个真正的正则表达式,它与右括号/花括号/ ...的数量相匹配。这意味着您的问题无法通过正则表达式解决。

话虽如此,大多数正则表达式库都有一个解决方案(使它们不是严格规则的。)平衡组是一种方法,正如杰里所写。 PERL正则表达式有recursive patterns

class([^{}]*\{[^{}]*(?1)*[^{}]*\}[^{}]*)

(?1)是第一个子模式的递归。