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)*[^{}]*\}[^{}]*)