将字符串中的所有十六进制转换为Redshift中的char值

时间:2016-05-04 20:46:18

标签: amazon-redshift

在Redshift中,我正在尝试转换这样的字符串:

http%3A%2F%2Fwww.amazon.com%2FTest%3Fname%3DGary%26Bob

看起来像这样:

http://www.amazon.com/Test?name=Gary&Bob

基本上我需要将字符串中的所有十六进制转换为其char值。我能想到的唯一方法是使用正则表达式函数。我尝试以两种不同的方式进行操作,并收到两者的错误消息:

SELECT REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])', CHR(x'\\1'::int))
ERROR: 22P02: "\" is not a valid hexadecimal digit

SELECT REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])',CHR(STRTOL('0x'||'\\1', 16)::int))
ERROR: 22023: The input 0x\1 is not valid to be converted to base 16

CHR和STRTOL功能独立运作。例如:

SELECT CHR(x'3A'::int)
SELECT CHR(STRTOL('0x3A', 16)::int)

都返回

:

如果我使用不同的函数(CHR和STRTOL除外)运行相同的模式,它可以工作:

REGEXP_REPLACE(hex_string, '%([[:xdigit:]][[:xdigit:]])', LOWER('{H}'||'\\1'||'{/H}'))

返回

http{h}3A{/h}{h}2F{/h}{h}2F{/h}www.amazon.com{h}2F{/h}Test{h}3F{/h}name{h}3D{/h}Gary{h}26{/h}Bob

但由于某些原因,这些函数无法识别正则表达式匹配组。

关于我如何做到这一点的任何提示?

我想另一个解决方案是对所有特殊的十六进制字符使用嵌套的REPLACE()函数,但这可能是最后的手段。

2 个答案:

答案 0 :(得分:4)

您要做的是“URL解码”。

目前没有内置功能可以执行此操作,但您可以创建自定义User-Defined Function(确保您拥有所需的privileges):

CREATE FUNCTION urldecode(url VARCHAR)
RETURNS varchar
IMMUTABLE AS $$
  import urllib
  return urllib.unquote(url).decode('utf8')  # or 'latin-1', depending on how the text is encoded
$$ LANGUAGE plpythonu;

示例查询:

SELECT urldecode('http%3A%2F%2Fwww.amazon.com%2FTest%3Fname%3DGary%26Bob');

结果:

http://www.amazon.com/Test?name=Gary&Bob

答案 1 :(得分:0)

我在REDSHIFT中尝试了@hiddenbit的答案,但不支持Python 3。但是,以下Py2代码确实对我有用:

g = (
    df.stack()
      .to_frame('Count')
      .rename_axis(index=['Age Range', 'Status'])
      .reset_index()
      .pipe((sns.factorplot, 'data'), 
            x='Age Range', y='Count',
            col='Status', kind='bar',
            size=3.5, aspect=1.86, col_wrap=2)

)