正则表达式:匹配表达式中最接近的左花括号和右花括号中的所有内容

时间:2018-09-21 03:08:06

标签: c# .net regex

很难解释我真正想要的是什么(更好的标题建议受到赞赏,以便以后人们可以轻松找到它)。

假设我有这个

{
    {
        $myTagThing$
    }
}

我想比赛

{
    $myTagThing$
} 

即匹配从{之前的最后$myTagThing$}之后的第一个$myTagThing$的所有内容。

所以我认为我需要这个\{.*\$myTagThing\$.*\},但它也将匹配字符串中的前{和后}(即整个示例)。然后,我尝试使用先行和后退(均为负)\{(.*(?!\{))\$myTagThing\$.*(?<!\})\}https://regex101.com/r/RfdHUH/1/)。但这仍然行不通。

我的理论是,由于这是我第一次使用它们,因此我可能会使用超前查找和错误查找的方式。

有什么想法吗?

编辑:标志为\gms

3 个答案:

答案 0 :(得分:4)

注意,该问题已被投票3次,并被标记为该问题revision 2的可接受答案,然后将该问题更改为其他方案,并且该答案未被接受

您需要查找:open-curly-brace,然后是不是open或close-curly-brace的字符序列,然后是close-curly-brace。

具体来说:{[^{}]*}

答案 1 :(得分:3)

编辑: 这解决了一个{ $myTagThing$ {} }场景,不再包含该问题。

关于您更新的问题。在.NET中,您想要的东西称为balanced groups。在其他正则表达式引擎中,balanced constructs/expressions。术语略有不同,引擎之间的语法也有很大差异,行为也是如此。

无论如何,要捕获最大的{}内容,您需要:

[^{}]*
(
((?'Open'{)[^{}]*)+
((?'Close-Open'})[^{}]*)+
)*
(?(Open)(?!))

(设置忽略空格标志或折叠此正则表达式)。这是您答案的核心。我们只是在这里用第一行和最后一行进行修改:

\{[^{}]*myTagThing
[^{}]*
(
((?'Open'{)[^{}]*)+
((?'Close-Open'})[^{}]*)+
)*
(?(Open)(?!))
[^{}]*\}

regex storm

“一个正则表达式”解决方案很快就会变得复杂,但是如果您经常使用.NET正则表达式,则可能会发现以下值得研究的地方:

Searching for specific text inside balanced chars (recursive

上面的链接是我在寻找类似以下字符串的问题:

Type VAR.*while{{VAR++}},其中while之后可以是平衡的{}。赏金授予的答案是您要查看的答案。这是一个比您的问题还要复杂的问题,但是您可以看到它变得非常疯狂:

另请参阅有关此功能的官方文档:

https://docs.microsoft.com/en-us/dotnet/standard/base-types/grouping-constructs-in-regular-expressions#balancing_group_definition

答案 2 :(得分:0)

另一种方法,修改了OP的原始方法:

\{{1}\s*\$myTagThing\$.*?\}

{1}表示与上一个字符完全匹配一次。 \s*捕获空白。 .*?使对右大括号的搜索变得非贪婪。

当然,如果事情是多行的,那么您也需要启用它。