具有平衡组的正则表达式适用于负前瞻但不适用于正前瞻(.net 方言)
Regex with balancing groups works with negative lookahead but not positive lookahead (.net dialect)
我发布了 的答案,其中 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 } }
个项目通过使用积极的前瞻性 - 还是我需要使用不同的东西?
您不需要正面前瞻,使用捕获和堆栈条件检查:
layer\s*{(?<f>\s*foo)?(?>{\s*foo(?<f>)(?<c>)|{(?<c>)|[^{}]+|}(?<-c>))*(?(c)(?!))(?(f)|(?!))}
兴趣点:
layer\s*{(?<f>\s*foo)?
- 添加一个可选的命名组 "f",如果在 layer {
+ 可选的空格数之后存在,则捕获 foo
。
(?>{\s*foo(?<f>)(?<c>)|
- 原子组内的第一个分支是与 {
(节点的开始)匹配的分支,后跟 foo
,如果匹配,则为 2堆栈递增:f
(foo 组)和 c
(左大括号组)。
(?(f)|(?!))
- 检查完 {
和 }
的平衡数后,这个条件构造检查 foo 栈是否不为空,如果不为空,则所有OK则返回匹配,否则匹配失败
我发布了
稍微简化一下问题 - 假设一些示例数据如下:
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 } }
个项目通过使用积极的前瞻性 - 还是我需要使用不同的东西?
您不需要正面前瞻,使用捕获和堆栈条件检查:
layer\s*{(?<f>\s*foo)?(?>{\s*foo(?<f>)(?<c>)|{(?<c>)|[^{}]+|}(?<-c>))*(?(c)(?!))(?(f)|(?!))}
兴趣点:
layer\s*{(?<f>\s*foo)?
- 添加一个可选的命名组 "f",如果在layer {
+ 可选的空格数之后存在,则捕获foo
。(?>{\s*foo(?<f>)(?<c>)|
- 原子组内的第一个分支是与{
(节点的开始)匹配的分支,后跟foo
,如果匹配,则为 2堆栈递增:f
(foo 组)和c
(左大括号组)。(?(f)|(?!))
- 检查完{
和}
的平衡数后,这个条件构造检查 foo 栈是否不为空,如果不为空,则所有OK则返回匹配,否则匹配失败