C#正则匹配最内层括号内容(含空括号)的实现需求
匹配字符串中最内层括号内容(支持空括号)
咱们来解决这个匹配最内层括号内容的问题,还要支持空括号的场景。你原来的正则\(([^()]+)\)有两个明显的问题:一是它要求括号里至少有一个非括号字符,完全处理不了()这种空括号;二是遇到嵌套括号时,它只会匹配第一个(到第一个)之间的内容,根本找不到最深层的目标括号。
我给你写个能用的正则,用了负向预查来精准定位最内层的有效括号:
var re = new Regex(@"\((?!.*\([^)]+\))([^()]*)\)", RegexOptions.Singleline);
我给你拆解一下这个正则的各个部分:
\(:匹配左括号;(?!.*\([^)]+\)):这是关键的负向预查,意思是当前括号内部不能存在任何非空括号(也就是不能有(xxx)这种结构,只能有()空括号);([^()]*):捕获括号里的内容,允许空内容,完美支持空括号;\):匹配右括号;RegexOptions.Singleline:可选参数,如果你的字符串里有换行符,这个选项能让.匹配换行,避免漏匹配。
然后把这个正则放到你的测试代码里,就能通过所有测试用例了:
var re = new Regex(@"\((?!.*\([^)]+\))([^()]*)\)", RegexOptions.Singleline); string[] tests = { "x (a) y", "a", "x (a b) y", "a b", "x (a b c) y", "a b c", "x (a b() c) y", "a b() c", "x (a() b() c) y", "a() b() c", "x (a b() c()) y", "a b() c()", "x (a b(a) c) y", "a", "x (a (b() c)) y", "b() c", "x () y", "" }; for (int i = 0; i < tests.Length; i+=2) { var match = re.Match(tests[i]); var result = match.Groups[1].Value; Assert.That(result, Is.EqualTo(tests[i + 1])); }
这个正则的逻辑很清晰:它会优先找那些内部没有非空括号的括号,这样自然就定位到了最内层的有效括号:
- 遇到嵌套的非空括号(比如
x (a b(a) c) y),最内层的(a)会被匹配,返回a; - 如果括号里只有空括号和普通内容(比如
x (a b() c) y),整个括号会被匹配,返回a b() c; - 空括号
()也能被正确识别,返回空字符串。
内容的提问来源于stack exchange,提问作者rednoyz
相关产品推荐
相关产品推荐

