Hive执行JSON存储的SQL时regexp_extract正则转义异常问题
问题原因
该问题是两层转义规则叠加、转义字符数量计算错误导致的,具体链路如下:
- JSON层面:JSON规范规定反斜杠
\是转义前缀字符,要在JSON字符串中表示1个字面意义的反斜杠,必须书写为\\;如果出现\s这类不在JSON合法转义序列范围内的写法,解析器会直接丢弃无效反斜杠,造成字符串内容错乱。 - Hive SQL层面:在Hive客户端直接执行SQL时,书写的
\\s、\\|会先被Hive的SQL解析器处理,将两个连续反斜杠转义为1个反斜杠,最终传递给正则引擎的模式为\s\|,这是符合正则语法、可以正确匹配「空白符+竖线」的正确模式。
最初在JSON中书写的\\s\\|,经JSON解析后传递给Hive的内容为\s\|。Hive解析字符串时,\s、\|不属于Hive认可的合法字符串转义序列,会直接丢弃反斜杠,最终正则引擎拿到的模式变为s|。正则语法中|是优先级最低的「或」运算符,此时模式(.*)s|等价于「匹配任意字符直到遇到第一个字符s,或匹配空字符串」。测试文本First part | Second Part中第一个s出现在Fir之后,因此返回结果为Fir。
后续修改的\\\s\\\|转义数量仍然错误:3个连续反斜杠经JSON解析后仅能得到1个字面反斜杠,传递给Hive转义后依然无法生成正确的正则模式,因此执行结果没有变化。
正确写法
只要保证JSON解析完成后,得到的SQL文本和Hive客户端中直接执行的测试SQL完全一致即可。
Hive客户端中书写的正则段'(.*)\\s\\|'共包含4个反斜杠,每个反斜杠都需要在JSON层面对应写2个反斜杠做转义,最终JSON里的正则段需要写为'(.*)\\\\s\\\\|'。
完整的正确JSON结构如下:
{ "name": "query1", "query": "select regexp_extract(column, '(.*)\\\\s\\\\|', 1) as column_one from data" }
可以先对该JSON做解析校验,打印query字段的内容,确认输出和Hive测试SQL完全一致后再执行,即可得到预期的First part结果。
内容的提问来源于stack exchange,提问作者legends1337
相关产品推荐
相关产品推荐

