【问题标题】:comparing strings in PostgreSQL比较 PostgreSQL 中的字符串
【发布时间】:2010-06-16 08:39:28
【问题描述】:

PostgreSQL 中是否有任何方法可以将 UTF-8 字符转换为“相似”的 ASCII 字符?

字符串glāžšķūņu rūķīši 必须转换为glazskunu rukisi。 UTF-8 文本不是某种特定语言,它可能是拉脱维亚语、俄语、英语、意大利语或任何其他语言。

这是在where 子句中使用时需要的,所以它可能只是“比较字符串”而不是“转换字符串”。

我尝试使用convert,但它没有给出想要的结果(例如,select convert('Ā', 'utf8', 'sql_ascii') 给出了\304\200,而不是A)。

数据库是通过以下方式创建的:

ENCODING = 'UTF8'
LC_COLLATE = 'Latvian_Latvia.1257'
LC_CTYPE = 'Latvian_Latvia.1257'

如有必要,可以更改这些参数。

【问题讨论】:

  • 我认为您将不得不自己编写。然后我们都可以使用它!

标签: postgresql search utf-8


【解决方案1】:

我在PostgreSQL Wiki 上找到了不同的方法。

在 plperl 中:

CREATE OR REPLACE FUNCTION unaccent_string(text) RETURNS text AS $$
my ($input_string) = @_;
$input_string =~ s/[âãäåāăą]/a;
$input_string =~ s/[ÁÂÃÄÅĀĂĄ]/A;
$input_string =~ s/[èééêëēĕėęě]/e;
$input_string =~ s/[ĒĔĖĘĚ]/E;
$input_string =~ s/[ìíîïìĩīĭ]/i;
$input_string =~ s/[ÌÍÎÏÌĨĪĬ]/I;
$input_string =~ s/[óôõöōŏő]/o;
$input_string =~ s/[ÒÓÔÕÖŌŎŐ]/O;
$input_string =~ s/[ùúûüũūŭů]/u;
$input_string =~ s/[ÙÚÛÜŨŪŬŮ]/U;
return $input_string;
$$ LANGUAGE plperl;

在纯 SQL 中:

CREATE OR REPLACE FUNCTION unaccent_string(text)
RETURNS text
IMMUTABLE
STRICT
LANGUAGE SQL
AS $$
SELECT translate(
    $1,
    'âãäåāăąÁÂÃÄÅĀĂĄèééêëēĕėęěĒĔĖĘĚìíîïìĩīĭÌÍÎÏÌĨĪĬóôõöōŏőÒÓÔÕÖŌŎŐùúûüũūŭůÙÚÛÜŨŪŬŮ',
    'aaaaaaaaaaaaaaaeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuu'
);
$$;

在plpython中:

create or replace function unaccent(text) returns text language plpythonu as $$
import unicodedata
rv = plpy.execute("select setting from pg_settings where name = 'server_encoding'");
encoding = rv[0]["setting"]
s = args[0].decode(encoding)
s = unicodedata.normalize("NFKD", s)
s = ''.join(c for c in s if ord(c) < 127)
return s
$$;

在您的情况下,使用您可以在 UTF-8 table 中找到的所有字符的 translate() 调用就足够了。

【讨论】:

  • 如果您需要有限的字符集(例如仅基于拉丁字母的字母),我认为这种纯 SQL 解决方案是最好的。它将很快,易于理解并且不需要任何非标准模块。只需从 ISO-8859-1、ISO-8859-2 和 ISO-8859-15 中获取所有字符 - 就足够了。
  • 目前使用纯SQL函数。虽然,它没有我希望的那么好......关于提到的字符编码 - 这还不够,因为它不包括拉脱维亚语(我来自拉脱维亚)和可能还有许多其他语言 - 至少 ISO-应添加 8859-4。为了使其更完整,我从en.wikipedia.org/wiki/Diacritic 中提取了所有带有变音符号的字母(只是将所有文本复制到记事本并使用 ctrl+h 删除了所有“标准”字符)并写了相同的拉丁字母,然后将其与示例中的字母连接起来由模拟提供。
【解决方案2】:

使用 pg_collkey() 进行 ICU 支持的 unicode 比较: - http://www.public-software-group.org/pg_collkey - http://russ.garrett.co.uk/tag/postgresql/

【讨论】:

  • 暂时不能尝试(不知道如何在Windows上编译)。根据我的阅读,我不确定 pg_collkey 是否适合我们,因为我们需要使用一些简单的模式,例如,字符串 %mazs%rukitis% 必须匹配 mazs glāžšķūņu rūķītis
猜你喜欢
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
相关资源
最近更新 更多