在sqlite中重音搜索(android)

时间:2012-12-29 16:05:25

标签: android sqlite android-sqlite

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

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

对于此要求,我尝试对该特定列使用“COLLATE NOCASE”参数。 但那没用。

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

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

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:0)

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

  

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

答案 2 :(得分:0)

在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)*"

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

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

此功能还用“转义”版本替换了GLOB*这两个?通配符。