jq 1.6/oniguruma 5.9.6 抛出 "Regex failure: invalid pattern in look-behind" 错误

jq 1.6/oniguruma 5.9.6 throws "Regex failure: invalid pattern in look-behind" error

问题

我正在尝试使用具有正则表达式的 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-behinddoc/RE 文件的第 221 行。

(?<!subexp) negative look-behind

Subexp of look-behind must be fixed character length. But different character length is allowed in top level alternatives only. ex. (?<=a|bc) is OK. (?<=aaa(?:b|cd)) is not allowed.

In negative-look-behind, captured group isn't allowed, but shy group(?:) is allowed.

看来我的表达应该有效。

经过一些测试后,我发现这行得通:

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 <>

有人知道哪里出了问题吗?

如果您当前的库版本仅限于 fixed-width 后视模式,您将无能为力。

在你的例子中,因为你使用的是负面回顾,你可以不用交替,只需将回顾分成两部分:

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

这样一来,您就不必关心每个回溯要检查多少个字符了。