【问题标题】:Convert hex to utf8 in greenplum in regexp_replace在regexp_replace的greenplum中将十六进制转换为utf8
【发布时间】:2012-09-19 09:16:37
【问题描述】:

我的表中有包含十六进制值的字符串,例如\ffffffc4。一个例子如下:

Urz\ffffffc4\ffffff85dzenie zgodne ze standardem High Definition Audio

以下代码可以将十六进制转换为UTF8:

select chr(x'c4'::int) 

它返回Ä,但是当我尝试使用 regexp_replace 时,我遇到了问题。我尝试了以下方法:

select regexp_replace(sal_input, E'\\f{6}(..)',convert(E'\\1','xyz','UTF8'),'g')

其中 XYZ 是 8.2 中提供的各种源编码,但我得到的只是十六进制值。

知道如何在regexp_replace 中使用 chr 函数吗?

使用的版本:x86_64-unknown-linux-gnu 上的 PostgreSQL 8.2.15(Greenplum Database 4.1.1.1 build 1)

提前感谢您的帮助

【问题讨论】:

  • 我刚刚意识到我在 SQL 代码中的双反斜杠被转换为单反斜杠。所以,上面的代码应该有 \\ 而不是 \
  • 您可以编辑您的帖子以反映这一点。
  • 顺便说一句,为什么这么古老的PostgreSQL? Greenplum 跟不上主线版本吗?
  • 不确定他们为什么不升级,但我猜这是因为这是一个生产系统并且停机时间是 NO-NO
  • @CraigRinger GP 基于 8.2.15,但某些 Postgres 功能被向后移植(?)/使用,并且从未与 Postgres 社区共享酷炫的增强功能。

标签: regex postgresql hex greenplum


【解决方案1】:

您误解了评估的顺序。 regexp_replace 的第二个参数不是每次替换 '\1' 时调用的回调。

发生的情况是,您的convert 调用在文字值\1 上被评估首先,然后将结果传递给regexp_replace

无论如何,由于更严格的转换规则,SQL 甚至不会在现代 PostgreSQL 上进行评估,因为 '\1' 不是有效的 bytea 文字。

在不那么古老的 Pg 版本中,可以使用 regexp_split_to_tablechrstring_agg 做一些事情。在 8.2 中,我认为您将使用 PL。我会加载PL/Perl 并编写一个简单的 Perl 函数来完成它。很可能在 PL/PgSQL 中实现,但我怀疑任何具有 8.2 中可用功能的实现都会冗长且缓慢。我很想被证明是错误的。

【讨论】:

  • 但是 regexp_replace 的文档说以下 regexp_replace(source, pattern, replacement [, flags ]) 我假设第二个参数(在这种情况下是 E'\\f{6}(.. )') 需要首先评估以找到将被替换的子字符串(如果有),并根据第三个参数(即 convert(E'\\1','xyz) 替换结果 (\1) ','UTF8').
  • @apostolos1975 如果您调用f(g('x')),评估顺序是总是,与函数无关,评估g('x') 以产生我们将调用的中间结果gx,然后评估 f(gx) 以产生最终结果。如果g(col) 在列引用col 上调用g,那么对于col 的每个值g(col) 都会被评估并传递给ffg 之前不会也永远不能被评估。 (有一些惰性求值的函数式语言可能不是这样,但一般来说 PostgreSQL 和 SQL 不是其中之一)。
  • ... 所以 首先convert(E'\\1','xyz','UTF8')文字参数 E'\\' 上进行评估,然后是 result 作为第三个参数传递给regexp_replace。您似乎希望为regexp_replace 找到的每个替换执行convert,但这不是它的工作原理。
猜你喜欢
  • 2020-06-29
  • 2013-03-07
  • 2013-10-02
  • 2020-06-15
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
相关资源
最近更新 更多