【问题标题】:Accented Search in sqlite (android)sqlite(android)中的重音搜索
【发布时间】:2012-12-29 16:05:25
【问题描述】:

我有一列,其中一些元素包含重音字母。 例如:Grambú

我的要求是,当我搜索“Grambu”时,我也应该在结果中得到“Grambú”。

对于这个要求,我尝试为该特定列使用“COLLATE NOCASE”参数。 但这没有用。

当我在网上搜索解决方案时,我发现很多人建议对重音字符进行规范化 并基于它创建另一列作为唯一选项。

对于这个问题还有其他更简单的解决方案吗?

【问题讨论】:

    标签: android sqlite android-sqlite


    【解决方案1】:

    COLLATE NOCASE 工作于only for the 26 upper case characters of ASCII

    使用setLocale() 将数据库的区域设置为支持重音字符的区域,并使用COLLATE LOCALIZED

    您也可以尝试使用COLLATE UNICODE。 但要注意这个错误:SQLite UNICODE sort broken in ICS - no longer case-insensitive

    查看the documentation 以了解 Android 中这两个收集器的提及。

    也可以看看这个online collation demo tool

    【讨论】:

    • 感谢您的重播。我在任何地方都找不到“COLLATE LOCALE”。我只能找到 COLLATE BINARY、NOCASE 和 RTRIM。
    • @RojilThomas 抱歉,这是一个错字。编辑了我的答案。
    • COLLATE LOCALIZED 在 title = 'Grambu' 的情况下为我工作,但当查询为 title LIKE '%格兰布%' .
    • 所以我的理解是,这里的 COLLATE 不适用于 LIKE,我必须使用第二个规范化列。
    • 您好,我们需要在哪里使用它?
    【解决方案2】:

    http://www.sqlite.org/lang_expr.html

    (一个错误:默认情况下,SQLite 只理解 ASCII 字符的大写/小写。默认情况下,LIKE 运算符对超出 ASCII 范围的 unicode 字符区分大小写。例如,表达式 'a' LIKE 'A'是 TRUE 但 'æ' LIKE 'Æ' 是 FALSE。)

    【讨论】:

      【解决方案3】:

      在 Android sqlite 中,LIKEGLOB 忽略 COLLATE LOCALIZEDCOLLATE UNICODE。但是,有一个解决方案,无需向表中添加额外的列。正如@asat 在this answer 中解释的那样,您可以将GLOB 与一个模式一起使用,该模式将用该字母的所有可用替代字母替换每个字母。在 Java 中:

      public static String addTildeOptions(String searchText) {
          return searchText.toLowerCase()
                           .replaceAll("[aáàäâã]", "\\[aáàäâã\\]")
                           .replaceAll("[eéèëê]", "\\[eéèëê\\]")
                           .replaceAll("[iíìî]", "\\[iíìî\\]")
                           .replaceAll("[oóòöôõ]", "\\[oóòöôõ\\]")
                           .replaceAll("[uúùüû]", "\\[uúùüû\\]")
                           .replace("*", "[*]")
                           .replace("?", "[?]");
      }
      

      然后(当然不是字面意思):

      SELECT * from table WHERE lower(column) GLOB "*addTildeOptions(searchText)*"
      

      这样,搜索 GrambuGrambú 的用户会将搜索转换为 Gramb[uúùüû],同时返回两个结果。

      注意GLOB 忽略COLLATE NOCASE 很重要,这就是为什么我在函数和查询中都将所有内容都转换为小写。另请注意,sqlite 中的 lower() 函数不适用于非 ASCII 字符 - 但这些可能是您已经替换的字符!

      该函数还将GLOB 通配符、*? 替换为“转义”版本。

      【讨论】:

        猜你喜欢
        • 2012-12-10
        • 2015-09-28
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 2013-06-28
        相关资源
        最近更新 更多