【问题标题】:Regex with balancing groups works with negative lookahead but not positive lookahead (.net dialect)具有平衡组的正则表达式适用于负前瞻,但不适用于正前瞻(.net 方言)
【发布时间】:2017-02-05 11:52:12
【问题描述】:

我发布了this question 的答案,其中 OP 想要一个正则表达式来匹配不同的 JSON 式数据块,条件是其中一个属性具有特定值。

稍微简化一下问题 - 假设一些示例数据如下:

layer { foo { bar { baz } } qux }
layer { fee { bar { baz } } qux }
layer { foo { bar { baz foo } } qux { quux quuux } }
{}
zip { layer { zop { layer {yeehah { foo } } } } }
zip { layer{ zop { layer {yeehah { fee } } } } }

正则表达式应匹配layer { .. stuff with nested data ...},但仅适用于存在foo 数据元素的情况。

我在答案中的正则表达式是:

layer\s*{(?>{(?<c>)|[^{}](?!fee)+|}(?<-c>))*(?(c)(?!))}

这不是积极识别包含foo 的匹配项,而是排除包含fee 的匹配项。如果所有非fee-items 都是foo-items,那很好,但其他线程上的问题并非如此。我的解决方案基本上将所有其他非foo-items 添加到负前瞻中,如下所示:

layer\s*{(?>{(?<c>)|[^{}](?!fee|blah|bloh|bluh|etc)+|}(?<-c>))*(?(c)(?!))}

但如果您事先不知道要排除的数据项,这是不切实际的。我尝试使用积极的前瞻:

layer\s*{(?>{(?<c>)|[^{}](?=foo)+|}(?<-c>))*(?(c)(?!))}

但这不起作用。

我的问题:谁能帮我重新编写正则表达式以匹配例如layer { foo { bar } } 项目通过使用积极的前瞻 - 还是我需要使用不同的东西?

【问题讨论】:

    标签: .net regex regex-lookarounds


    【解决方案1】:

    您不需要积极的前瞻,使用捕获和堆栈条件检查:

    layer\s*{(?<f>\s*foo)?(?>{\s*foo(?<f>)(?<c>)|{(?<c>)|[^{}]+|}(?<-c>))*(?(c)(?!))(?(f)|(?!))}
    

    regex demo

    兴趣点:

    • layer\s*{(?&lt;f&gt;\s*foo)? - 添加了一个可选的命名组“f”,用于捕获foo(如果存在于layer { + 可选数量的空格之后)。
    • (?&gt;{\s*foo(?&lt;f&gt;)(?&lt;c&gt;)| - 原子组内的第一个分支是与foo 后跟{(节点开始)匹配的分支,如果匹配,则增加2 个堆栈:f(foo 组)和c(左大括号组)。
    • (?(f)|(?!)) - 在检查{} 的平衡数之后,此条件构造检查 foo 堆栈是否为空,如果不为空,则一切正常,匹配返回,如果不是,匹配失败。

    【讨论】:

      猜你喜欢
      • 2012-06-21
      • 1970-01-01
      • 2021-10-11
      • 2011-10-14
      • 2010-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多