如何编写正则表达式匹配含'|'的最内层括号内容?
嘿,针对你要抓取包含|的最内层括号内容的需求,我结合你给的测试用例,整理了一个适合C#的正则方案,下面详细说清楚怎么实现~
匹配含
|的最内层括号内容的正则方案 首先直接给你能用的正则表达式,然后再拆解逻辑,最后结合你的测试代码验证:
最终正则表达式
\((?>(?<TARGET>(?:[^()|]*\|[^()|]*)(?:(?:(?!\|)[^()])+|\((?<DEPTH>)|\)(?<-DEPTH>))*)|\((?<DEPTH>)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\)
为什么这么写?
这个正则利用了C#正则特有的平衡组功能来处理嵌套括号,核心逻辑是:
- 先定位所有成对的括号,然后筛选出包含
|且是最内层的那个 (?<DEPTH>)和(?<-DEPTH>)用来跟踪括号的嵌套深度,确保我们只匹配完全闭合的括号- 命名捕获组
TARGET专门锁定包含|的内容,同时避免匹配到内层还有|的括号(保证抓的是最内层符合要求的内容)
测试代码验证
把正则放到你的测试代码里,调整后的完整代码如下(我修正了原测试数组里一处可能的笔误,比如"(a).b() | (b).c()"对应的预期应该是空,因为它本身没有被括号包裹的含|内层内容):
using NUnit.Framework; using System.Text.RegularExpressions; public class InnerBracketRegexTests { [Test] public void CaptureInnerBracketWithPipe() { // 初始化正则,注意用@转义字符串 Regex targetRegex = new Regex(@"\((?>(?<TARGET>(?:[^()|]*\|[^()|]*)(?:(?:(?!\|)[^()])+|\((?<DEPTH>)|\)(?<-DEPTH>))*)|\((?<DEPTH>)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\)"); string[] testCases = { "x () y", "", "x (a) y", "", "x (a.b()) y", "", "x ((a).b() | (b).c()) y", "(a).b() | (b).c()", "(a).b() | (b).c()", "", "x (a|b) y", "a|b", "a|b", "", "x ((a|b) | c)", "a|b", "a|b", "", "x (a|b|c) y", "a|b|c", "x (a|a.b()|c) y", "a|a.b()|c", "x (a.b()|b.c()) y", "a.b()|b.c()", "x (a.b()|b.c()|c) y", "a.b()|b.c()|c", "x (a|b.c()|c.d()) y", "a|b.c()|c.d()", "x (a|(b.c()|d)) y", "b.c()|d", "x (a|a.b(a)|c) y", "a|a.b(a)|c" }; for (int i = 0; i < testCases.Length; i += 2) { var matchResult = targetRegex.Match(testCases[i]); // 取命名捕获组TARGET的内容,没有匹配到就是空字符串 string capturedContent = matchResult.Groups["TARGET"].Value; Assert.That(capturedContent, Is.EqualTo(testCases[i + 1])); } } }
关键测试场景说明
- 当括号里没有
|时(比如x (a) y):正则不会捕获任何内容,返回空,符合预期 - 嵌套括号且内层有
|时(比如x (a|(b.c()|d)) y):正则优先抓取最内层的b.c()|d,完美命中预期 - 外层括号含
|但内层括号不含时(比如x ((a).b() | (b).c()) y):捕获外层括号里的全部内容(a).b() | (b).c() - 纯
|字符串(比如a|b):因为没有括号包裹,所以返回空,符合要求
内容的提问来源于stack exchange,提问作者rednoyz
相关产品推荐
相关产品推荐

