我正在寻找一种方法来以大小写不敏感的方式比较和排列C++中的UTF-8字符串以在custom collation function in SQLite中使用它。用于SQLite的不区分大小写的UTF-8字符串整理(C/C++)
- 该方法应该理想情况下是区域独立的。但是,就我所知,我不会屏住呼吸,因为排序规则是非常依赖语言的,所以任何对英语以外的语言都适用的东西都可以,即使它意味着切换语言环境。
- 选项包括使用标准C或C++库或小型(适用于嵌入式系统)和非GPL(适用于专有系统)的第三方库。
我有什么至今:
strcoll
使用C语言环境和std::collate
/std::collate_byname
是区分大小写的。 (是否有这些不区分大小写的版本?)我试图使用POSIX strcasecmp,但它似乎是not defined比
"POSIX"
在POSIX语言环境,strcasecmp其他区域设置()和strncasecmp()从上到下进行转换,然后进行字节比较。结果在其他语言环境中未指定。
而且,事实上,中
strcasecmp
结果没有语言环境之间在Linux上用glibc改变。#include <clocale> #include <cstdio> #include <cassert> #include <cstring> const static char *s1 = "Äaa"; const static char *s2 = "äaa"; int main() { printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); assert(setlocale(LC_ALL, "en_AU.UTF-8")); printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); assert(setlocale(LC_ALL, "fi_FI.UTF-8")); printf("strcasecmp('%s', '%s') == %d\n", s1, s2, strcasecmp(s1, s2)); printf("strcoll('%s', '%s') == %d\n", s1, s2, strcoll(s1, s2)); }
这会打印:
strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == -32 strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == 7 strcasecmp('Äaa', 'äaa') == -32 strcoll('Äaa', 'äaa') == 7
PS
是的,我知道关于ICU,但我们不能用它在嵌入式平台上,由于其enormous size 。
关于德国“ß”字符(以及所有如此丰富的案例)的例子:这些字符必须已经被“解决”或以其他方式处理过数千次,UTF-8或否。 MS Word一直有一个“切换大小写”功能 - 它在Unicode之前的版本中是如何工作的? WordPerfect如何? 我有和OP一样的问题,除了我在Delphi工作。我见过很多基于Windows sqlite的应用程序,它们执行不区分大小写的SELECT(我猜ORDER BY),无论它们是以英语,德语还是(在我的情况下)波兰语区域安装。试试Firefox :)他们如何做到这一点? – 2009-10-17 23:19:23