gpt4 book ai didi

Postgresql levenshtein 和预组合字符与组合字符

转载 作者:行者123 更新时间:2023-11-29 11:56:06 27 4
gpt4 key购买 nike

我有包含两个相似字符的字符串。两者都显示为带有 ogonek 的小“a”:

±

±

(注意:根据渲染器,它们有时呈现相似,有时略有不同)

但是,它们是不同的:

第一个字符的特征:

在 PostgreSQL 中:

select ascii('ą');
ascii
-------
261

十六进制的 UTF-8 编码是:\xC4\x85

所以它是一个预组合字符 ( https://en.wikipedia.org/wiki/Precomposed_character )

第二个字符的特征:

在 PostgreSQL 中:

select ascii('ą');
ascii
-------
97

(与字符'a'相同)

这强烈表明渲染的字符是由两个字符组合而成的。它确实是:

十六进制的 UTF-8 编码是:\x61\xCC\xA8

所以是组合

一个\x61\

和一个组合字符 ( https://en.wikipedia.org/wiki/Combining_character ),单独的 ogonek:

̨ \xCC\xA8

我想使用 PostgreSQL 的 levenshtein 函数来确定单词的相似性,因此我想将两个字符视为相同的(因为这当然是写一个独特名称的人的意图)具有第一个或第二个字符的实体)。

我假设我可以使用 unaccent 来始终摆脱 ogonek,但这在第二种情况下不起作用:

第一个字符:预期结果:

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

第一个字符:预期结果:

select levenshtein(unaccent('ą'), 'x');
levenshtein
-------------
1

第二个字符:预期结果:

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

第二个字符:意外结果:

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

所以,当我将两个字符与 levenshteinunaccent 进行比较时,结果是 1:

select levenshtein(unaccent('ą'), unaccent('ą'));
levenshtein
-------------
1

而不是 0。

在第二种情况下,我怎样才能“摆脱 ogonek”?

(如何)使用String的UTF-8编码可以得到实现的结果?

编辑:正如@s-man 建议的那样,将组合字符添加到unaccent.rules 将解决这个特定问题。但是要普遍解决预组合字符与组合字符unaccent问题,我必须明确添加/修改每个缺失/“错误配置”组合字符到/在配置中。

最佳答案

移除重音符号会让编辑距离为 0,但它也会让 ±a 之间的距离为 0,这听起来并不理想。

更好的解决方案是 normalise Unicode 字符串,即将组合字符序列 E'a\u0328' 转换为预组合字符 E'\u0105',然后再进行比较。

不幸的是,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;

然后:

test=# select levenshtein(unicode_normalize(E'a\u0328'), unicode_normalize(E'\u0105'));
levenshtein
-------------
0

这也解决了 your previous question 中的问题,其中组合字符对 Levenshtein 距离有贡献:

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

关于Postgresql levenshtein 和预组合字符与组合字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56683034/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com