postgresql 10.1 中的 utf-8 字符串相似度
utf-8 string similarity in postgresql 10.1
:) 我试图在 PostgreSQL 10.1 中查找字符串相似性。
我使用扩展 unaccent
和 pg_trgm
并通过以下方式启用它们:
create extension unaccent;
create extension pg_trgm;
问题是pg_trgm
不提供utf8支持。所以如果我执行:
select similarity('כפיר','כפיר');
它return相似度为零。
我决定将该字符串转换为支持希伯来语和英语的 iso-8859-8
编码,这是我在本例中使用的语言。
但首先我想 unaccent
字符串,所以如果我有 כפיר - ƒ
它将首先被转换为 כפיר - f
这样它就会被正确地转换为所需的字符编码。
所以 select unaccent('כפיר - ƒ');
会 return 正确的结果。
所以不幸执行:
select convert(unaccent('כפיר - ƒ'),'UTF8','ISO_8859_8');
returns
[42883] ERROR: function convert(text, unknown, unknown) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 8
当我查看 https://www.postgresql.org/docs/9.1/functions-string.html 上关于 convert()
函数的文档时,它需要一个字符串。
如果我尝试将某些内容转换为字符串,我会得到 type "string" does not exist
好的。所以使用 unaccent 是我需要解决的第一个问题(也许是唯一的问题)。我接下来做了什么return在没有看到正确的希伯来语字符串的情况下得到了正确的结果。
我的意思是这个..
正在执行 select convert('כפיר','UTF-8','ISO_8859_8');
returns
4 B 00000000 EB F4 E9 F8 ëôéø
并使用 select convert('כפיר','UTF8','ISO_8859_8')::text;
returns \xebf4e9f8
将其转换为文本
我猜这些是书写字符,由于编码的变化,我看不到真正的希伯来字符。我的假设是错误的吗?这是第二期。
所以如果我不使用重音并执行:
select similarity(convert('כפייר עזר','UTF8','ISO_8859_8')::text, convert('כפיר','UTF8','ISO_8859_8')::text);
它 return 的相似度为 0.5,这没问题。
综上所述,我的问题是:
- 如何正确投射
unaccent
以便能够在 convert
中使用它
- 我是否将 utf-8 希伯来语字符串正确转换为 ASCII?
- 我是否尝试以正确的方式解决问题 - 是否有支持 utf-8 的相似函数的不同扩展?
- 我还想在执行相似度函数之前从字符串中删除任何不是字母数字的字符,以便根据我的需要获得更好的相似度结果。我考虑使用正则表达式将字符串转换为 ASCII。类似于:
regexp_replace('string', '\W+', '', 'g')
。那是要走的路吗?有没有支持utf8的regexp_replace?
谢谢!
好的,所以解决方案很简单。
需要将其转换为字节数组 (bytea
),然后再转换回文本。
关于正则表达式替换,我应该使用我想删除的特定字符而不是使用 \W+
.
所以我的情况的解决方案是:
select
similarity(convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text,
convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text)
:) 我试图在 PostgreSQL 10.1 中查找字符串相似性。
我使用扩展 unaccent
和 pg_trgm
并通过以下方式启用它们:
create extension unaccent;
create extension pg_trgm;
问题是pg_trgm
不提供utf8支持。所以如果我执行:
select similarity('כפיר','כפיר');
它return相似度为零。
我决定将该字符串转换为支持希伯来语和英语的 iso-8859-8
编码,这是我在本例中使用的语言。
但首先我想 unaccent
字符串,所以如果我有 כפיר - ƒ
它将首先被转换为 כפיר - f
这样它就会被正确地转换为所需的字符编码。
所以 select unaccent('כפיר - ƒ');
会 return 正确的结果。
所以不幸执行:
select convert(unaccent('כפיר - ƒ'),'UTF8','ISO_8859_8');
returns
[42883] ERROR: function convert(text, unknown, unknown) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Position: 8
当我查看 https://www.postgresql.org/docs/9.1/functions-string.html 上关于 convert()
函数的文档时,它需要一个字符串。
如果我尝试将某些内容转换为字符串,我会得到 type "string" does not exist
好的。所以使用 unaccent 是我需要解决的第一个问题(也许是唯一的问题)。我接下来做了什么return在没有看到正确的希伯来语字符串的情况下得到了正确的结果。
我的意思是这个..
正在执行 select convert('כפיר','UTF-8','ISO_8859_8');
returns
4 B 00000000 EB F4 E9 F8 ëôéø
并使用 select convert('כפיר','UTF8','ISO_8859_8')::text;
returns \xebf4e9f8
我猜这些是书写字符,由于编码的变化,我看不到真正的希伯来字符。我的假设是错误的吗?这是第二期。
所以如果我不使用重音并执行:
select similarity(convert('כפייר עזר','UTF8','ISO_8859_8')::text, convert('כפיר','UTF8','ISO_8859_8')::text);
它 return 的相似度为 0.5,这没问题。
综上所述,我的问题是:
- 如何正确投射
unaccent
以便能够在convert
中使用它
- 我是否将 utf-8 希伯来语字符串正确转换为 ASCII?
- 我是否尝试以正确的方式解决问题 - 是否有支持 utf-8 的相似函数的不同扩展?
- 我还想在执行相似度函数之前从字符串中删除任何不是字母数字的字符,以便根据我的需要获得更好的相似度结果。我考虑使用正则表达式将字符串转换为 ASCII。类似于:
regexp_replace('string', '\W+', '', 'g')
。那是要走的路吗?有没有支持utf8的regexp_replace?
谢谢!
好的,所以解决方案很简单。
需要将其转换为字节数组 (bytea
),然后再转换回文本。
关于正则表达式替换,我应该使用我想删除的特定字符而不是使用 \W+
.
所以我的情况的解决方案是:
select
similarity(convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text,
convert(unaccent(regexp_replace(lower('string'), '[.,''׳`"-]', '', 'g'))::bytea,'UTF8','ISO_8859_8')::text)