【问题标题】:How to use case insensitive pattern matching with PostgreSQL and Umlauts?如何在 PostgreSQL 和 Umlauts 中使用不区分大小写的模式匹配?
【发布时间】:2010-06-23 19:17:38
【问题描述】:

当字符串包含非 ASCII 字符(如德语变音符号)时,我试图让 PostgreSQL 8.4.3 使用其 ~* 运算符进行不区分大小写的模式匹配。数据库、终端和其他一切都配置为使用 UTF-8。

简而言之就是问题所在:

SELECT 'Ö' ~* 'ö';      -- false

还有其他变体可以工作:

SELECT 'Ö' ILIKE 'ö';     -- true
SELECT 'Ö' ~* '[Öö]';     -- true
SELECT LOWER('Ö') ~* 'ö'; -- true

这些选择都没有让我特别高兴。 ILIKE 不使用正则表达式。 [Öö] 涉及重写搜索词。 LOWER() 可能是最好的解决方法,但我真的很想让~* 运算符按预期工作。

提前致谢。

【问题讨论】:

  • 变音符号和单词边界存在相关问题。例如,模式 '\möl' 将不匹配字符串 'öl'。

标签: postgresql design-patterns case-insensitive matching diacritics


【解决方案1】:

这是 PostgreSQL 9.0 之前版本中的一个错误。
它在 9.0 更新日志中:http://www.postgresql.org/docs/9.0/static/release-9-0.html#AEN99075

这是我在 9.0 beta2 中使用 Ubuntu 进行的测试:

SELECT 'Ö' ~* 'ö';
 ?column? 
----------
 t
(1 row)

【讨论】:

  • 谢谢,这就解释了。现在我至少可以停止寻找我们设置的问题了。
【解决方案2】:

我对这个查询是正确的:

SELECT 'Ö' ~* 'ö'; -- true

但我确实在 OS X 10.5.8 上使用了 9.0beta2 版本并具有以下设置:

CREATE DATABASE test
  WITH OWNER = postgres
       ENCODING = 'UTF8'
       TABLESPACE = pg_default
       LC_COLLATE = 'nl_NL.UTF-8'
       LC_CTYPE = 'nl_NL.UTF-8'
       CONNECTION LIMIT = -1;

编辑:版本 8.3.7 上的结果相同。看来你的编码有问题。

【讨论】:

  • 非常有趣,感谢您的检查。我无法让它在任何地方工作。我的本地数据库服务器(Ubuntu 8.10 上的 v8.3.9)不允许我在 CREATE DATABASE 语句中指定 LC_COLLATE 或 LC_CTYPE。我认为这些是在 8.4 中添加的。没有它们,新数据库中的结果是相同的。服务器上的数据库(Ubuntu 10.04 上的 v8.4.3)要求我指定 TEMPLATE=t​​emplate0 才能创建具有“nl_NL.UTF-8”语言环境的数据库,但即便如此,结果仍然相同(不匹配)。
  • 嗯,我在 Ubuntu 9.10、PostgreSQL 8.4.4 上也得到了 FALSE。 (在 OS X 上运行的虚拟机)。我猜它在创建 db-cluster 时与 innitdb 有关。看看它和/或向 pgsql-mailinglist 发送消息。
  • 在 Fedora 12 上使用 8.4.3 也获得了 FALSE。(使用 LATIN9 进行集群初始化,但它让我通过指定 TEMPLATE = template0; 创建数据库 abose
  • 顺便说一句,首先要检查我们没有弄乱终端 i/o,应该检查一下,例如:SELECT encode('Ö','hex') 给出 c396(使用 UTF8)
  • 还可以查看以下内容:SELECT 'Ö' ~* 'ö' COLLATE "de_DE";
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-08
  • 2020-07-27
相关资源
最近更新 更多