Impala Regex 前瞻和后视的解决方法

Posted

技术标签:

【中文标题】Impala Regex 前瞻和后视的解决方法【英文标题】:Workaround for Impala Regex lookahead and lookbehind 【发布时间】:2018-07-11 03:44:41 【问题描述】:

如果我使用 Hive,则以下工作正常。但是如果我使用 Impala,它会抛出错误:

select regexp_replace("foobarbarfoo","bar(?=bar)","<NA>");

WARNINGS: Could not compile regexp pattern: bar(?=bar)
Error: invalid perl operator: (?=

基本上,Impala 不支持前瞻和后瞻

https://www.cloudera.com/documentation/enterprise/release-notes/topics/impala_incompatible_changes.html#incompatible_changes_200

今天有解决方法吗?也许使用UDF?

谢谢。

【问题讨论】:

【参考方案1】:

由于您使用的是regexp_replace,因此匹配并捕获您想要保留的字符串部分(但想要用作必须具有的上下文)并替换为反向引用。见regexp_replace Impala reference:

这些示例展示了如何使用替换文本替换与模式匹配的部分字符串,其中可以包括对模式字符串中任何() 组的反向引用。反向引用编号从 1 开始,任何 \characters 都必须转义为 \\

所以,在这里,你可以使用

select regexp_replace("foobarbarfoo","bar(bar)","<NA>\\1");
                                         ^   ^       ^^^   

请注意,它不能替换连续匹配,但是,它可以在当前场景和foobarbarfoo will turn into foo&lt;NA&gt;barfoo 中工作(请注意,Go 正则表达式引擎也是 RE2,因此在 regex101.com 上选择了此选项)。

【讨论】:

我得到了foo&lt;NA&gt;$1foo 是回报。因此,反向引用 $1 没有做任何事情……至少对于 Impala。 @HP。然后尝试\1 语法。 "&lt;NA&gt;\1""&lt;NA&gt;\\1" \\1 工作...... Cloudera 文档中在哪里提到了这个?是否也有“前向引用”? @HP。是的,刚刚找到here。

以上是关于Impala Regex 前瞻和后视的解决方法的主要内容,如果未能解决你的问题,请参考以下文章

RegEx - 正向后视中的可选子字符串

Mod Rewrite Regex - 多个负前瞻

Java 正则表达式错误 - 使用组参考进行后视

负前瞻正则表达式贪婪(为啥.*?太贪婪)

Impala Regex:匹配字符 a 和 b 之间的字符串(如果 b 存在)

Impala find_in_set 用百分号匹配 LIKE