Postgres中的Unicode规范化

时间:2014-07-21 11:14:52

标签: postgresql unicode plpython

我有大量苏格兰和威尔士语重音的地名(结合严重,急性,旋律和深度)我需要更新为他们的unicode规范化形式,例如{{1的更短形式00E1(\ xe1)而不是0061 + 0301(\ x61 \ x301)

我使用pl / python从2009年的旧Postgres nabble邮件列表中找到了解决方案,

á

这正如预期的那样有效,但让我想知道是否有任何方法可以直接使用内置的Postgres函数。我尝试使用convert_to进行各种转换,都是徒劳的。

编辑:正如克雷格指出的那样,以及我尝试的其中一件事:

create or replace function unicode_normalize(str text) returns text as $$
  import unicodedata
  return unicodedata.normalize('NFC', str.decode('UTF-8'))
$$ LANGUAGE PLPYTHONU;

返回SELECT convert_to(E'\u00E1', 'iso-8859-1'); ,而

\xe1

SELECT convert_to(E'\u0061\u0301', 'iso-8859-1');

失败

1 个答案:

答案 0 :(得分:10)

我认为这是一个Pg错误。

在我看来,PostgreSQL应该在执行编码转换之前将utf-8规范化为预先组合的形式。显示的转换结果是错误的。

我会在pgsql-bugs上完成它...完成。

http://www.postgresql.org/message-id/53E179E1.3060404@2ndquadrant.com

你应该可以关注那里的主题。

编辑:pgsql-hackers似乎不同意,所以这不太可能匆忙改变。我强烈建议您在应用程序输入边界上规范化UTF-8。

顺便说一下,这可以简化为:

regress=> SELECT 'á' = 'á';
 ?column? 
----------
 f
(1 row)

这是简单的疯狂谈话,但是被允许。第一个是预先组合,第二个不是。 (要查看此结果,您必须复制和粘贴,并且只有在您的浏览器或终端不规范化utf-8时才能正常工作。)

如果您使用的是Firefox,可能无法正确看到上述情况; Chrome正确呈现它。如果您的浏览器正确处理分解的Unicode,您应该看到以下内容:

Decomposed vs precomposed unicode á showing false for equality