捕获外部 paren/bracket 组,同时忽略内部 paren 组

Capture outer paren/bracket groups while ignoring inner paren groups

这是我的 . The answer worked perfectly for me until I ran into an edge case that caused a problem. I now need a tweaked regex pattern. I have tried to work it out on my own at Regex Storm 的排列,但我对正则表达式的了解还不够先进。

与我之前的 post(上面链接)相比的一个变化是,我现在只对匹配以 ([ 开头的括号分组感兴趣,而不仅仅是 (。分组的结尾保持不变:)

为了完整起见,这里是之前的整个问题,针对新要求进行了修改:

我正在使用 C# 和正则表达式,尝试捕获外部括号组而忽略内部括号组。我有遗留生成的文本文件,其中包含数千个字符串结构,如下所示:

([txtData] of COMPOSITE
(dirty FALSE)
(composite [txtModel])
(view [star3])
(creationIndex 0)
(creationProps )
(instanceNameSpecified FALSE)
(containsObject nil)
(sName txtData)
(txtDynamic FALSE)
(txtSubComposites )
(txtSubObjects )
(txtSubConnections )
)

([txtUI] of COMPOSITE
(dirty FALSE)
(composite [txtModel])
(view [star2])
(creationIndex 0)
(creationProps )
(instanceNameSpecified FALSE)
(containsObject nil)
(sName ApplicationWindow)
(txtDynamic FALSE)
(txtSubComposites )
(txtSubObjects )
(txtSubConnections )
)

([star38] of COMPOSITE
(dirty FALSE)
(composite [txtUI])
(view [star39])
(creationIndex 26)
(creationProps composite [txtUI] sName Bestellblatt)
(instanceNameSpecified TRUE)
(containsObject COMPOSITE)
(sName Bestellblatt)
(txtDynamic FALSE)
(txtSubComposites )
(txtSubObjects )
(txtSubConnections )
)

我正在寻找一个正则表达式,它将捕获上面示例中的 3 个分组,这是上一个 SO post:

的解决方案
Regex regex = new Regex(@"\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)"); 
return regex.Matches(str);

我需要对上面的正则表达式模式稍作调整,以便它只匹配以 ([ 开头的分组,而不仅仅是以 ( 开头的分组。结尾还是一样:)

需求匹配很简单:

  1. 左括号 + 方括号 (([) 是文件中的第一个字符,或者跟在 newline.
  2. 之后
  3. 右括号是文件中的最后一个字符,或者后跟 newline

我希望正则表达式模式忽略所有不遵守上面数字 1 和 2 的双亲分组。 “忽略”是指不应将它们视为匹配项 - 但应将它们作为外部分组匹配项的一部分返回。

因此,为了满足我的 objective,当我的 C# 正则表达式与上面的示例运行时,我应该取回恰好有 3 个匹配项的正则表达式 MatchCollection,如上所示。

怎么做到的?

您可以在需要 [ 初始 ( 之后的模式开始处应用正前瞻。此外,由于前导 ([ 只能出现在行首而结束 ) 只能出现在行尾,因此添加 ^ 和 [=16 是有意义的=] 锚点(注意 \r? 是必要的,因为 $ 在多行模式中只匹配 \n 之前的位置,而不是 \r 之前的位置)。

因此,您的正则表达式可能会调整为

var results = Regex.Matches(text, 
                  @"^\((?=\[)(?>\((?<c>)|[^()]+|\)(?<-c>))*\)\r?$", 
                  RegexOptions.Multiline)
              .Cast<Match>()
              .Select(x => x.Value)
              .ToList();

参见.NET regex demo

详情

  • ^ - 行首
  • \( - 一个 ( 字符
  • (?=\[) - [ 应该紧跟在当前位置
  • 之后
  • (?>\((?<c>)|[^()]+|\)(?<-c>))* - 0 次或多次重复
    • \((?<c>)| - ( 并将空值推送到“组”c 捕获堆栈,或
    • [^()]+| - ()
    • 以外的 0 个或更多字符
    • \)(?<-c>) - ) 并且从“c”组捕获堆栈中弹出一个空值
  • \) - 一个 ) 字符
  • \r?$ - 可选的 CR 和行尾。