ios - 如何处理 iOS SQLite 中的重音字符?

标签 ios sqlite cultureinfo diacritics

我需要执行对大小写和重音不敏感的 SELECT 查询。出于演示目的,我创建了一个这样的表:

create table table
(
  column text collate nocase
);

insert into table values ('A');
insert into table values ('a');
insert into table values ('Á');
insert into table values ('á');

create index table_cloumn_Index
  on table (column collate nocase);

然后,我在执行以下查询时得到这些结果:

SELECT * FROM table WHERE column LIKE 'a';
> A
> a

SELECT * FROM table WHERE column LIKE 'á';
> á

SELECT * FROM table WHERE column LIKE 'Á';
> Á

我怎样才能解决这个问题,使以下任何查询的结果都像这样:

> A
> a
> Á
> á

顺便说一下,sqlite 在 iOS 上运行。

提前致谢

最佳答案

两种基本方法:

  1. 您可以在表中创建第二列,其中包含不含国际字符的字符串。此外,在针对此辅助搜索列进行搜索之前,您还应该从正在搜索的字符串中删除国际字符(这样您就可以将非国际字符与非国际字符进行比较)。

    这是我用来转换国际字符的例程:

    NSData *data = [string dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    

    您还可以将重音字符替换为:

    NSMutableString *mutableString = [string mutableCopy];
    CFStringTransform((__bridge CFMutableStringRef)mutableString, NULL, kCFStringTransformStripCombiningMarks, NO);
    

    顺便说一下,如果您需要对结果进行排序,您也可以根据这个辅助搜索字段而不是主字段进行排序,这也可以避免 SQLite 无法对国际字符进行排序的问题。

  2. 您也可以创建自己的“无重音”C 函数(在您的类的@implementation 之外定义此 C 函数):

    void unaccented(sqlite3_context *context, int argc, sqlite3_value **argv)
    {
        if (argc != 1 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
            sqlite3_result_null(context);
            return;
        }
    
        @autoreleasepool {
            NSMutableString *string = [NSMutableString stringWithUTF8String:(const char *)sqlite3_value_text(argv[0])];
            CFStringTransform((__bridge CFMutableStringRef)string, NULL, kCFStringTransformStripCombiningMarks, NO);
            sqlite3_result_text(context, [string UTF8String], -1, SQLITE_TRANSIENT);
        }
    }
    

    然后你可以定义一个调用这个C函数的SQLite函数(打开数据库后调用这个方法,直到你关闭数据库才会生效):

    - (void)createUnaccentedFunction
    {
        if (sqlite3_create_function_v2(database, "unaccented", 1, SQLITE_ANY, NULL, &unaccented, NULL, NULL, NULL) != SQLITE_OK)
            NSLog(@"%s: sqlite3_create_function_v2 error: %s", __FUNCTION__, sqlite3_errmsg(database));
    }
    

    完成后,您现在可以在 SQL 中使用这个新的 unaccented 函数,例如:

    if (sqlite3_prepare_v2(database, "select a from table where unaccented(column) like 'a'", -1, &statement, NULL) != SQLITE_OK)
        NSLog(@"%s: insert 1: %s", __FUNCTION__, sqlite3_errmsg(database));
    

关于ios - 如何处理 iOS SQLite 中的重音字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10356062/

相关文章:

ios - 在 Objective-C 中使用 RSSI 每秒查找最近的信标

ios - UITextField成为FirstReponder不工作并返回false

ios - 如何使用 Swift 的 Decodable 来解析您只知道或只关心几个字段的任意 JSON 字符串?

.net - 如何使用相应的RegionInfo.GeoId获取所有国家

c# - StreamWriter 和 IFormatProvider

ios - 从 [PFObject] 向下转换为 [PFObject]

android - SQLiteOpenHelper 空指针异常

django - 将数据库同步到 python django

java - 使用 SQLite 数据库填充列表

C# Mysql cultureinfo.invariantculture