我发布了this question的答案,其中OP希望正则表达式匹配不同的JSON-esque数据块,其中一个属性具有特定值。
稍微简化一下这个问题 - 假设一些样本数据如下:
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
- 项都是foo
项,那就没问题了 - 但是另一个问题上的问题并非如此。我的解决方案基本上将所有其他非foo
- 项添加到负面预测中,如下所示:
layer\s*{(?>{(?<c>)|[^{}](?!fee|blah|bloh|bluh|etc)+|}(?<-c>))*(?(c)(?!))}
但如果您事先不知道要排除的数据项,这是不切实际的。我尝试使用积极的前瞻:
layer\s*{(?>{(?<c>)|[^{}](?=foo)+|}(?<-c>))*(?(c)(?!))}
但这不起作用。
我的问题:任何人都可以帮我重新编写正则表达式以匹配例如layer { foo { bar } }
使用积极的前瞻项目 - 或者我需要使用不同的东西吗?
答案 0 :(得分:1)
您不需要积极的前瞻,使用捕获和堆叠条件检查:
layer\s*{(?<f>\s*foo)?(?>{\s*foo(?<f>)(?<c>)|{(?<c>)|[^{}]+|}(?<-c>))*(?(c)(?!))(?(f)|(?!))}
请参阅regex demo
的POI:
layer\s*{(?<f>\s*foo)?
- 添加了一个可选的命名组“f”,可以在foo
+可选的空格数后显示layer {
。(?>{\s*foo(?<f>)(?<c>)|
- 原子组内的第一个分支是一个与{
(节点的开头)匹配的分支,后跟foo
,如果匹配,则有2个堆栈递增:f
(foo组)和c
(开括号组)。(?(f)|(?!))
- 在检查了{
和}
的平衡数后,此条件结构检查foo堆栈是否为空,如果它不为空,则一切正常,返回匹配,否则匹配失败。