我有一列,其中一些元素包含重音字母。例如:格拉姆布
我的要求是,当我搜索“Grambu”时,我也应该在结果中得到“Grambu”。
对于这个要求,我尝试为该特定列使用“COLLATE NOCASE”参数。但这没有用。
当我在网上搜索解决方案时,我发现很多人建议标准化重音字符并基于它创建另一个列作为唯一选项。
这个问题还有其他更简单的解决方案吗?
我有一列,其中一些元素包含重音字母。例如:格拉姆布
我的要求是,当我搜索“Grambu”时,我也应该在结果中得到“Grambu”。
对于这个要求,我尝试为该特定列使用“COLLATE NOCASE”参数。但这没有用。
当我在网上搜索解决方案时,我发现很多人建议标准化重音字符并基于它创建另一个列作为唯一选项。
这个问题还有其他更简单的解决方案吗?
COLLATE NOCASE
仅适用于 ASCII 的 26 个大写字符。
将数据库的语言环境设置为具有重音字符支持 usingsetLocale()
和 use的语言环境COLLATE LOCALIZED
。
您也可以尝试使用COLLATE UNICODE
. 但要注意这个错误:ICS 中的 SQLite UNICODE 排序被破坏 - 不再区分大小写。
检查文档以在 Android 中提及这两个整理器。
另请查看此在线校对演示工具。
http://www.sqlite.org/lang_expr.html
(一个错误:默认情况下,SQLite 只理解 ASCII 字符的大写/小写。默认情况下,LIKE 运算符对超出 ASCII 范围的 unicode 字符区分大小写。例如,表达式 'a' LIKE 'A' 为 TRUE 但'æ' LIKE 'Æ' 是 FALSE。)
在 Android sqlite 中LIKE
,GLOB
忽略COLLATE LOCALIZED
和COLLATE UNICODE
。但是,有一个解决方案,无需向表中添加额外的列。正如@asat 在此答案中解释的那样,您可以使用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
ignores COLLATE NOCASE
,这就是为什么我在函数和查询中都将所有内容都转换为小写。另请注意lower()
,sqlite 中的函数不适用于非 ASCII 字符 - 但这些可能是您已经替换的字符!
该函数还将GLOB
通配符*
和?
, 替换为“转义”版本。