使用RegEx平衡匹配括号

Ice*_*ind 30 .net c# regex

我正在尝试创建一个.NET RegEx表达式,它将正确地平衡我的括号.我有以下RegEx表达式:

func([a-zA-Z_][a-zA-Z0-9_]*)\(.*\)
Run Code Online (Sandbox Code Playgroud)

我想要匹配的字符串是这样的:

"test -> funcPow((3),2) * (9+1)"
Run Code Online (Sandbox Code Playgroud)

应该发生什么是正则表达式应该匹配从funcPow第二个右括号到第二个右括号.它应该在第二个右括号后停止.相反,它一直匹配到最后一个右括号.RegEx将返回此:

"funcPow((3),2) * (9+1)"
Run Code Online (Sandbox Code Playgroud)

它应该返回:

"funcPow((3),2)"
Run Code Online (Sandbox Code Playgroud)

任何有关这方面的帮助将不胜感激.

Sco*_*pey 51

正则表达式绝对可以做平衡括号匹配.它可能很棘手,需要一些更高级的Regex功能,但这并不难.

例:

var r = new Regex(@"
    func([a-zA-Z_][a-zA-Z0-9_]*) # The func name

    \(                      # 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!

    \)                      # Last ')'
", RegexOptions.IgnorePatternWhitespace);
Run Code Online (Sandbox Code Playgroud)

平衡匹配组具有几个功能,但是对于此示例,我们仅使用捕获删除功能.该行将(?<-open> \) )匹配a )并删除先前的"打开"捕获.

最棘手的是(?(open)(?!)),让我解释一下. (?(open)是一个条件表达式,仅在存在"打开"捕获时才匹配. (?!)是一个总是失败的否定表达.因此,(?(open)(?!))说"如果有一个开放捕获,那么失败".

微软的文档也非常有用.


xan*_*tos 22

使用平衡组,它是:

Regex rx = new Regex(@"func([a-zA-Z_][a-zA-Z0-9_]*)\(((?<BR>\()|(?<-BR>\))|[^()]*)+\)");

var match = rx.Match("funcPow((3),2) * (9+1)");

var str = match.Value; // funcPow((3),2)
Run Code Online (Sandbox Code Playgroud)

(?<BR>\()|(?<-BR>\))是一个平衡组(BR我用的名称是Brackets).以这种方式更清楚(?<BR>\()|(?<-BR>\))也许,这样,\(并且\)更"明显".

如果你真的讨厌自己(以及世界/你的同事共同编程)足以使用这些东西,我建议RegexOptions.IgnorePatternWhitespace到处使用和"洒"白色空间:-)

  • 仅供记录,包含 `(?(BR)(?!))` 和不包含它之间的区别在于,如果没有它,表达式将_匹配_直到并包括最后一个右括号(如果没有_足够_结束)括号。有了它,整个表达式将_不匹配_。 (2认同)