有没有办法通过 HQL/SQL 解析带有转义的 csv 字符串?

Is there a way to parse csv string with escapings via HQL/SQL?

我在解析存储在随后加载到 PostgreSQL 数据库中的 Hive table 列中的 csv 格式数据时遇到问题。我需要做的是从那里检索一些字段,但是,如果引用了逗号,则应将其视为要检索的数据的一部分;最重要的是,引号可以自己转义。这是我尝试过的方法、结果如何以及预期的输出结果:

考虑这个字符串:a,b,c,"d,e,1","dj+""17"""

输出应该是这样的:a b c d,e,1 dj+"17"

我尝试使用 regexp_extract,如下所示: regexp_extract(data,'(,?(".*?"|[^,]*)){1}',2).

它几乎按照我想要的方式工作,唯一的问题是它不能使用转义引号正常工作:它在我想要的基础上将 "dj+""17""" 拆分为 dj+ 17 <empty string>去做。

我发现 Hive 允许您使用 CSVSerde 解决此类任务,但是,我只看到它在数据存储在文本文件中时被使用,而事实并非如此。这个问题有解决方法吗?

P.S.: 我在 Hive 和 Hadoop 方面总体上缺乏专业知识,所以我可能不了解某些原理和可用功能

可以用逗号分隔字符串,后跟偶数个引号或零个引号,如果逗号在引号内则不分隔。这仅在您只有平衡报价时才有效(每个报价都有相应的收盘价)。

代码(蜂巢):

with mytable as(
select 'a,b,c,"d,e,1","dj+""17"""' as original_string
) 
select --remove quotes at the beginning and at the end of the string
       regexp_replace(splitted[0],'^"(.*?)"$','') as col1,
       regexp_replace(splitted[1],'^"(.*?)"$','') as col2,
       regexp_replace(splitted[2],'^"(.*?)"$','') as col3,
       regexp_replace(splitted[3],'^"(.*?)"$','') as col4,
       regexp_replace(splitted[4],'^"(.*?)"$','') as col5
from
(
select split(original_string, ',(?=(?:[^"]*"[^"]*")*[^"]*$)') as splitted from mytable
)s;

结果:

col1    col2    col3    col4    col5
a       b       c       d,e,1   dj+""17""

正则表达式 ',(?=(?:[^"]*"[^"]*")*[^"]*$)' 表示:

, - 逗号

(?= - 后跟组(零长度正向前看)开始

(?:[^"]*"[^"]*") --non-capturing group consisting of 0+ non-quote, quote, 0+ non-quote, quote

*组重复0+

$ - 字符串结尾

) - 后面的组结束(正向展望)

要取消引用 "d,e,1" 等元素,使用表达式 regexp_replace(str,'^"(.*?)"$','')。如果字符串有开始和结束引号,它会删除它们。

此外,您可能还想用单引号替换两个双引号,以将 dj+""17"" 这样的值转换为 dj+"17"