我有大量带有苏格兰和威尔士口音的地名(结合了重音、尖音、抑扬音和分音符),我需要将它们更新为它们的 unicode 规范化形式,例如, 的较短形式 00E1 (\xe1) á
而不是 0061 + 0301 (\x61\x301)
我使用 pl/python 从 2009 年的旧 Postgres nabble 邮件列表中找到了解决方案,
create or replace function unicode_normalize(str text) returns text as $$
import unicodedata
return unicodedata.normalize('NFC', str.decode('UTF-8'))
$$ LANGUAGE PLPYTHONU;
这如预期的那样有效,但让我想知道是否有任何方法可以直接使用内置的 Postgres 函数来完成它。我尝试了各种使用 convert_to 的转换,但都是徒劳的。
编辑:正如 Craig 所指出的,以及我尝试过的其中一件事:
SELECT convert_to(E'\u00E1', 'iso-8859-1');
返回 \xe1
,而
SELECT convert_to(E'\u0061\u0301', 'iso-8859-1');
失败并出现 错误:编码“UTF8”的字符 0xcc81 在“LATIN1”中没有等效项
最佳答案
我认为这是一个 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,您应该看到以下内容:
关于postgresql - Postgres 中的 Unicode 规范化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24863716/