我正在尋找一種方法來以大小寫不敏感的方式比較和排列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