如何在SQLite查询中忽略重音(Android)

and*_*uza 20 sqlite android diacritics

我是Android的新手,我正在使用SQLite进行查询.我的问题是,当我在字符串中使用重音时,例如

  • AAA
  • AAA
  • AAA
  • AAA
  • AAA
  • AAA

如果我做:

SELECT * FROM TB_MOVIE WHERE MOVIE_NAME LIKE '%a%' ORDER BY MOVIE_NAME;
Run Code Online (Sandbox Code Playgroud)

回归:

  • AAA
  • aaa(它忽略了其他人)

但如果我这样做:

SELECT * FROM TB_MOVIE WHERE MOVIE_NAME LIKE '%à%' ORDER BY MOVIE_NAME;
Run Code Online (Sandbox Code Playgroud)

回归:

  • ààà(忽略标题"ÀÀÀ")

我想在SQLite数据库中选择字符串而不关心重音和大小写.请帮忙.

laa*_*lto 37

通常,SQL中的字符串比较由列或表达式COLLATE规则控制.在Android中,只预定义了三个校对序列:BINARY(默认),LOCALIZED和UNICODE.它们都不适合您的用例,遗憾的是,Java API中没有公开用于安装新归类函数的C API.

要解决这个问题:

  1. 例如,向表中添加另一列 MOVIE_NAME_ASCII
  2. 将值存储到此列中并删除重音符号.因为NFD代表重音符号大致为纯ASCII +结合口音标记您可以通过标准化的字符串转换为Unicode范式d(NFD),并删除非ASCII码点去除口音:

    String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
        .replaceAll("[^\\p{ASCII}]", "");
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您的文本是否在此ASCII规范化列上搜索,但显示原始unicode列中的数据.

  • 也适合我,但我想知道是否没有其他方法可以做到这一点 (4认同)

des*_*ado 5

在 Android sqlite 中,LIKEGLOB忽略两者COLLATE LOCALIZEDCOLLATE UNICODE(它们仅适用于ORDER BY)。但是,有一种无需向表中添加额外列的解决方案。正如@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("?", "[?]");
}
Run Code Online (Sandbox Code Playgroud)

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

SELECT * from table WHERE lower(column) GLOB "*addTildeOptions(searchText)*"
Run Code Online (Sandbox Code Playgroud)

这样,例如在西班牙语中,搜索masmás的用户会将搜索转换为m[aáàäâã]s,返回两个结果。

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

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