Postgresql正则表达式匹配大写字母,支持Unicode

3
标题已经很清楚了。我正在寻找适用于Postgres ~运算符的Unicode大写字母的正则表达式。 显然的方式不能工作:
=> select 'A' ~ '[[:upper:]]';
 ?column? 
----------
 t
(1 row)

=> select 'Ó' ~ '[[:upper:]]';
 ?column? 
----------
 t
(1 row)

=> select 'Ą' ~ '[[:upper:]]';
 ?column? 
----------
 f
(1 row)

我正在使用Postgresql 9.1版本,我的本地化语言设置为pl_PL.UTF-8。排序功能正常。

=> show LC_CTYPE;
  lc_ctype   
-------------
 pl_PL.UTF-8
(1 row)

1
在我本地的PostgreSQL 9.2.1上(但不是9.1.6上),Ą[[:upper:]]匹配。 - araqnid
@araqnid 对我来说,在9.2中也有匹配项。如果您尝试使用9.1中的排序规则会怎样呢?:select 'Ą' ~ '[[:upper:]]' collate "pl_PL" - Clodoaldo Neto
@Clodoaldo 明确指定排序规则对结果没有影响。 - araqnid
看起来这是一个在9.2中最终修复的错误? - janek37
1
可能与bug #6457有关,当时报告后得到了修复(但据我所知在发布说明中没有提到)。 - Daniel Vérité
2个回答

4
PG 9.1及更早版本的正则表达式引擎无法正确分类代码点不符合一个字节的字符。代码点为211的'Ó'是正确的,但代码点为260的'Ą'超过了255。PG 9.2在这方面做得更好,尽管对于所有字母表仍不完全正确。请参阅PostgreSQL源代码中的commit,特别是评论的这些部分:

移除硬编码的限制,不考虑255以上的字符代码的wctype.h结果

尽管如此,我们可以将其推高到U+7FF(我选择作为2字节UTF8字符的限制),这将至少使东欧人感到高兴,等待更好的解决方案

不幸的是,这并没有被回溯到9.1。


1
我发现 Perl 正则表达式完美地处理了 Unicode。
create extension plperl;

create function is_letter_upper(text) returns boolean
immutable strict language plperl
as $$
    use feature 'unicode_strings';
    return $_[0] =~ /^\p{IsUpper}$/ ? "true" : "false";
$$;

在使用Perl 5.16.2和PostgreSQL 9.2进行测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接