是否有支持多字节的 Postgresql Levenshtein?

Joh*_*ied 5 postgresql utf-8 levenshtein-distance

当我使用fuzzystrmatch levenshtein函数与变音符号一起使用时,它返回错误/多字节无知的结果:

\n\n
select levenshtein(\'a\xcc\xa8\', \'x\');\nlevenshtein \n-------------\n       2\n
Run Code Online (Sandbox Code Playgroud)\n\n

(注意:第一个字符是一个“a”,下面有一个变音符号,我复制到这里后它没有正确呈现)

\n\n

fuzzystrmatch文档(https://www.postgresql.org/docs/9.1/fuzzystrmatch.html)警告:

\n\n
\n

目前,soundex、metaphone、dmetaphone 和 dmetaphone_alt 函数不能很好地处理多字节编码(例如 UTF-8)。

\n
\n\n

但由于它没有命名levenshtein函数,我想知道是否有 levenshtein的多字节感知版本的多字节感知版本。

\n\n

我知道我可以使用非重音函数作为解决方法,但我需要保留变音符号。

\n

Joh*_*ied 2

\n

注意:此解决方案是@Nick Barnes 在回答相关问题时建议的。

\n
\n\n

带有变音符号的 \'a\' 是一个字符序列,即a和组合字符的组合,变音符号 \xcc\xa8 :E\'a\\u0328\'

\n\n

有一个等效的预组合字符\xc4\x85E\'\\u0105\'

\n\n

解决方案是标准化Unicode 字符串,即在比较它们之前将组合字符序列转换为预组合字符。

\n\n

不幸的是,Postgres 似乎没有内置的 Unicode 规范化功能,但您可以通过PL/PerlPL/Python语言扩展轻松访问该功能。

\n\n

例如:

\n\n
create extension plpythonu;\n\ncreate or replace function unicode_normalize(str text) returns text as $$\n  import unicodedata\n  return unicodedata.normalize(\'NFC\', str.decode(\'UTF-8\'))\n$$ language plpythonu;\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在,当使用 将字符序列E\'a\\u0328\'映射到等效的预组合字符时,编辑距离是正确的:E\'\\u0105\'unicode_normalize

\n\n
select levenshtein(unicode_normalize(E\'a\\u0328\'), \'x\');\nlevenshtein\n-------------\n           1\n
Run Code Online (Sandbox Code Playgroud)\n

  • [Postgres 现在包含一个 `normalize` 函数(从版本 13 开始)](https://www.postgresql.org/docs/13/functions-string.html#id-1.5.8.10.5.2.2.7.1.1.1 )。 (2认同)