Postgres中的Unicode规范化

Joh*_*ell 17 postgresql unicode plpython

我有大量苏格兰和威尔士的重音地名(结合严重,急性,旋律和暗音),我需要更新到他们的unicode规范化形式,例如,更短的形式00E1(\ xe1)á代替0061 + 0301(\X61\X301)

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

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

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

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

SELECT convert_to(E'\u00E1', 'iso-8859-1');
Run Code Online (Sandbox Code Playgroud)

返回\xe1,而

SELECT convert_to(E'\u0061\u0301', 'iso-8859-1');
Run Code Online (Sandbox Code Playgroud)

失败了 ERROR: character 0xcc81 of encoding "UTF8" has no equivalent in "LATIN1"

Cra*_*ger 11

我认为这是一个Pg bug.

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

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

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

你应该能够在那里跟随线程.

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

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

regress=> SELECT 'a?' = 'á';
 ?column? 
----------
 f
(1 row)
Run Code Online (Sandbox Code Playgroud)

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

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

分解与预组合的unicodeá显示为平等的假