postgresql - 是否有一个多字节感知 Postgresql Levenshtein?
问题描述
当我使用带有变音符号的fuzzystrmatch levenshtein函数时,它返回一个错误/多字节无知的结果:
select levenshtein('ą', 'x');
levenshtein
-------------
2
(注意:第一个字符是一个'a',下面有一个变音符号,我在这里复制后没有正确呈现)
Fuzzystrmatch文档( https://www.postgresql.org/docs/9.1/fuzzystrmatch.html ) 警告说:
目前,soundex、metaphone、dmetaphone 和 dmetaphone_alt 函数不适用于多字节编码(例如 UTF-8)。
但由于它没有命名levenshtein函数,所以我想知道是否有 levenshtein的多字节感知版本。
我知道我可以使用unaccent函数作为解决方法,但我需要保留变音符号。
解决方案
带有变音符号的 'a' 是一个字符序列,即 a和一个组合字符的组合,变音符号 ̨ :E'a\u0328'
有一个等效的预组合字符ą:E'\u0105'
一种解决方案是规范化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'
映射到等效的预组合字符上E'\u0105'
,unicode_normalize
因此 levenshtein 距离是正确的:
select levenshtein(unicode_normalize(E'a\u0328'), 'x');
levenshtein
-------------
1
推荐阅读
- angular - 如何将 Angular 8 与 gradle 集成?
- ios - 来自 firebase 动态链接的 URL 检测返回 nil iOS
- android - 具有多个活动的 JetPack 导航组件?
- gradle - 添加约束布局后无法同步项目
- c# - 使用多个筛选器的 Azure 搜索
- laravel - 缺少路由所需的参数:仪表板 URI:laravel 中的仪表板/{id}
- visual-studio-code - vscode live share:在本地运行共享代码
- inheritance - Kotlin 接口实现打破了 `equals` 覆盖
- java - 在eclipse中运行TestNG程序时出现错误:发生JNI错误,请检查您的安装并重试
- python - 从文本文件中提取数据并将其转换为 df