Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何编写一个可以忽略嵌套捕获的正则表达式?_C#_Regex - Fatal编程技术网

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

C# 如何编写一个可以忽略嵌套捕获的正则表达式?,c#,regex,C#,Regex,我正在尝试编写一个正则表达式,其中包含以下内容: class bob { ... } class joe { { ... } } class tim { { ... } { ... } } 和输出(为简单起见减少了空白) 我试过类[\s]+([\w]+)[\s]*{([^}]*},但(可以理解)在第一个“

我正在尝试编写一个正则表达式,其中包含以下内容:

 class bob
 {
       ...
 }

 class joe
 {
       {
            ...
       }
 }

 class tim
 {
       {
            ...
       }
       {
            ...
       }
 }
和输出(为简单起见减少了空白)

我试过
类[\s]+([\w]+)[\s]*{([^}]*}
,但(可以理解)在第一个“}”处停止

我也尝试过
类[\s]+([\w]+)[\s]*{(.*)}
但是它贪婪地攫取一切直到最后一个'}'

现在,我不在乎外括号里是什么——只是我抓住了它

作为一个额外的“乐趣”,我不希望有新的行(或者类[\s]之外的任何特定空格),这样类bob{}class joe{}将[理论上]成为一个有效的输入字符串)


不,我不是在做一个完整的或真正的标记器/解析器,而是我自己的代码可视化工具(如果我完成了这个附带项目的话)。

您可以使用平衡组:

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
)\}
class\s*([^{]+?)\s*\{(#匹配类和第一个“{”
(?:                 
[^{}]#匹配所有非大括号
|
(?\{)匹配“{”,并捕获到“打开”
|
(?\})匹配“}”,并删除“打开”捕获
)+
(?(打开)(?!)#如果“打开”堆栈不是空的,则失败
)\}

如果您输入注释和缩进,请确保具有
RegexOptions.IgnoreWhitespace
标志。

严格来说,正则表达式无法处理递归。因此,您无法编写一个真正的正则表达式来匹配右括号/花括号/的数量和左括号/的数量。这表示您的问题无法用正则表达式解决

也就是说,大多数正则表达式库都有一个解决方案(使它们不是严格的正则表达式)。正如Jerry所写,平衡组是一种方法。PERL正则表达式有:


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

是否需要处理多个级别的嵌套大括号?@Flimzy Yeah.编辑以修复它。@KendallFrey我可能会得到任意数量的嵌套大括号。你确定要使用正则表达式吗?因为这非常复杂(并且无法移植到其他语言)。一个合适的解析器只是更好。特别是如果你担心字符串或注释中的大括号应该被忽略,等等@KendallFrey如果“抓取所有类及其内容”变得很复杂,那么是的,我会转而制作一个解析器。不过,你说的“可移植到其他语言”是什么意思?它是否处理类A{const string multiline=@“}类Fake{…}”;}@Codism如果你修改它,它可以处理它。没有提到类似的东西,所以我没有走那么远。另外,我不应该知道OP可能具有的所有边缘情况,我的正则表达式应该能够引导他们在正确的方向。正确的方向不应该使用正则表达式。无意冒犯,但这是我的第一个想法恩,我看到这样的答案。@Codism好吧,你可以有你自己的观点,我有我自己的。如果你认为你有更好的解决方案,你可以把它作为你知道的答案发布?@Jerry这确实回答了我的问题(不是你的错,我错过了一个边缘案例——可能不止一个)在我开始调查这件事之后,我一直在努力平衡群体。
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
)\}
class([^{}]*\{[^{}]*(?1)*[^{}]*\}[^{}]*)