首页 > 解决方案 > jq 1.6/oniguruma 5.9.6 抛出“Regex failure: invalid pattern in look-behind”错误

问题描述

问题

我正在尝试使用jq v1.6具有正则表达式的过滤器,其中包含否定的后视和否定的前瞻表达式,但它们失败了Regex failure: invalid pattern in look-behind,即使规范似乎是一个有效的表达式。

我正在使用的命令是

$ jq -n '("baz", "foo baz", "bla baz", "baz bars") | test("(?<!foo |bars )baz(?! foo| bars)")'
jq: error (at <unknown>): Regex failure: invalid pattern in look-behind

似乎jq 1.6正在使用 Onigurama 库版本 5.9.6(https://github.com/stedolan/jq/commit/61edf3fa93f6177ef099b1b0cb2b49813a35c546#diff-ea6712465e6d2ae84a07da73f4ad6e25,这似乎是正确的脚本版本,因为jq 1.6它是在 2018 年 11 月发布的,并且下一次提交compile-ios.sh直到 2019 年 12 月)。

现在,我能找到的 Oniguruma 5.9.6 最接近的文档来自 5.9.1(在https://github.com/kkos/oniguruma/commit/65a9b1aa03c9bc2dc01b074295b9603232cb3b78#中,您可以搜索文件的negative look-behind第 221 行doc/RE

(?<!subexp) 负面回顾

后视的子表达式必须是固定的字符长度。但仅在顶级备选方案中允许使用不同的字符长度。前任。(?<=a|bc) 没问题。(?<=aaa(?:b|cd)) 是不允许的。

在消极的后视中,不允许捕获组,但允许害羞组(?:)。

所以看起来我的表达应该有效。

在测试了一些东西之后,我发现这是可行的:

jq -n '("baz", "foo baz", "bla baz", "baz bars") | test("(?<!foo|bar)baz(?! foo| bars)")'

唯一的区别是后视表达式替代项是固定宽度,但文档明确指出顶级替代项允许具有可变宽度。

结论

似乎由于某种原因,这个特定版本jq不支持(负)后视表达式中的可变宽度替代方案,即使规范对此没有任何说明。

笔记

我怀疑jq我安装的特定版本出现了问题,因为如果我尝试在https://stedolan.github.io/jq/manual/#RegularexpressionsPCRE中运行正则表达式示例,也会出现错误:

$ jq -n '("test", "TEst", "teST", "TEST") | test( "(?i)te(?-i)st" )'
jq: error (at <unknown>): Regex failure: invalid group name <>

有谁知道可能出了什么问题?

标签: regexjqpcreregex-lookaroundsnegative-lookbehind

解决方案


如果您当前的库版本仅限于固定宽度的后视模式,那么您将无能为力。

在您的情况下,由于您使用的是负面的后视,您可以不交替进行,只需将后视分成两部分:

(?<!foo )(?<!bars )baz(?! foo| bars)
^^^^^^^^^^^^^^^^^^^

然后,您不必关心每个后视必须检查多少个字符。


推荐阅读