postgresql - Postgres 中的 Unicode 规范化

标签 postgresql unicode plpython

我有大量带有苏格兰和威尔士口音的地名(结合了重音、尖音、抑扬音和分音符),我需要将它们更新为它们的 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,您应该看到以下内容:

Decomposed vs precomposed unicode á showing false for equality

关于postgresql - Postgres 中的 Unicode 规范化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24863716/

相关文章:

sql - PL/Python 错误 : NameError: global name 'name of user-defined function' is not defined

postgresql - plpython,plpythonu,plpython2u有什么区别

postgresql - 在查询 PostgreSQL 数据库的黑盒函数上使用 multiprocessing.Pool 时为 "InterfaceError: connection already closed"

database - 如何查询 PostgreSQL 数据库列是否一个项目出现多次

python - 与 PostgreSQL 全文搜索的部分匹配

java - 如何知道我的 HTTP 请求是否使用 UTF-8?

regex - 使用 Perl 发出匹配重音字符

ruby-on-rails - Rails 重置所有 Postgres 序列?

c - c中打印宽字符的问题

python - PostgreSQL 如何追加执行查询的多个结果?