问题描述
问题
我正在尝试使用具有正则表达式的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
。
(?
后向子表达式必须为固定字符长度。 但是顶层允许使用不同的字符长度 仅替代品。 例如(?
在背后隐藏表情的情况下,不允许捕获的组, 但允许害羞的组(?:)。
所以看来我的表情应该有用。
在测试了几件事之后,我发现这可行:
jq -n '("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 <>
有人知道什么地方可能出问题吗?
解决方法
如果您当前的库版本仅限于固定宽度的后向模式,那么您将无法做很多事情。
在您的情况下,由于您使用的是负向后置,因此您无需更改即可,只需将后置分为两部分即可:
(?<!foo )(?<!bars )baz(?! foo| bars)
^^^^^^^^^^^^^^^^^^^
然后,您不必担心每个后代必须检查多少个字符。