postgresql - 是否有多字节感知的 Postgresql Levenshtein?

标签 postgresql utf-8 levenshtein-distance

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

select levenshtein('ą', 'x');
levenshtein 
-------------
       2

(注意:第一个字符是'a',下面有变音符号,我在这里复制后显示不正确)

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

At present, the soundex, metaphone, dmetaphone, and dmetaphone_alt functions do not work well with multibyte encodings (such as UTF-8).

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

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

最佳答案

Note: This solution was suggested by @Nick Barnes in his answer to a related question.

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

有一个等效的预组合字符±:E'\u0105'

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

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

例如:

create extension plpythonu;

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

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

select levenshtein(unicode_normalize(E'a\u0328'), 'x');
levenshtein
-------------
           1

关于postgresql - 是否有多字节感知的 Postgresql Levenshtein?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56676187/

相关文章:

sql - where 子句括号中的逗号分隔值大于

Python UTF-8 转换

algorithm - 找到所有成对的相似词

sql - 当数据库时间片大于想要的时间片时,如何查询时间序列数据?

sql - 多个多对多双向自内连接,无需重复整个查询

c# - 在 C# 中将字符串 (UTF-16) 转换为 UTF-8

c++ - 在 unordered_map 的键上实现 "did you mean"

r - 模糊匹配电影标题,无需使用循环并按发行日期提取等效标题

sql - 在 PostgreSQL 中获取一个范围内的日期列表

java - 字符被转换为特殊字符