首页 > 解决方案 > 仅当前面没有制表符或空格时才匹配括号组

问题描述

我的 c# 正则表达式代码:

Regex regex = new Regex(@"\((.*?)\)");
return regex.Matches(str);

...很好地匹配下面数据块中的所有“paren组”:

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

但是下面的数据块让它偏离了轨道:

([vog317] of ZZconstant
(dirty FALSE)
(composite [gpGame])
(view [nil])
(creationIndex 1)
(creationProps composite !/gpGame sName Constraint4)
(instanceNameSpecified TRUE)
(containsObject ZZconstant)
(sName NoGo_Track_back_Co)
(description "")
(parameters "")
(languageType Prefix)
(explanation "Some sample text here!")
(salience 1)
(condition "

        (if     (eq ?hoer9_Cl:sName extens)

                then

            (or (eq ?Starry:sName sb405)
                (eq ?Starry:sName sb43)
                (eq ?Starry:sName sb455)
                (eq ?Starry:sName sb48)
            )

        )

")
)

请注意 inner-paren 组:

       (if      (eq ?hoer9_Cl:sName extens)

                then

            (or (eq ?Starry:sName sb405)
                (eq ?Starry:sName sb43)
                (eq ?Starry:sName sb455)
                (eq ?Starry:sName sb48)
            )

        )

括号括起来的数据的那个小子块应该仅仅被视为(condition括号组的一部分,而不是与正则表达式模式匹配。排除它的方法是让模式查看以下两个异常之一:

那么如何修改我的正则表达式模式\((.*?)\)以使其符合上述两条规则?我在Regex Storm中尝试了一段时间,但我对 regex 的初学者太过分了,无法解决。

标签: c#regexregex-group

解决方案


您可以使用您尝试过的模式,并为列出的 2 个例外中的逻辑添加外观:

(?<![ \t])\((?!if\s)(.*?)\)

解释

  • (?<![ \t])第一点的否定后视断言直接在左边的不是空格或制表符
  • \(匹配(
  • (?!if\s)负前瞻第二点断言直接在右边的不是if和空白字符
  • (.*?)捕获组 1匹配除换行符以外的任何字符非贪婪
  • \)匹配)

正则表达式演示

如果左括号和右括号之间的匹配可以跨越多行,您还可以使用否定字符类[^

(?<![ \t])\((?!if\s)([^()]*)\)

正则表达式演示


推荐阅读