Accented Search in sqlite (android)

前端 未结 3 884
时光取名叫无心
时光取名叫无心 2020-12-11 08:30

I have a column where some of the elements contain accented letters. eg : Grambú

My requirement is that when I search for \"Grambu\" I should get \"Grambú\" in the r

3条回答
  •  無奈伤痛
    2020-12-11 08:56

    In Android sqlite, LIKE and GLOB ignore both COLLATE LOCALIZED and COLLATE UNICODE. However, there is a solution without having to add extra columns to your table. As @asat explains in this answer, you can use GLOB with a pattern that will replace each letter with all the available alternatives of that letter. In 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("?", "[?]");
    }
    

    And then (not literally like this, of course):

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

    This way, a user searching for either Grambu or Grambú will get the search converted into Gramb[uúùüû], returning both results.

    It is important to notice that GLOB ignores COLLATE NOCASE, that's why I converted everything to lower case both in the function and in the query. Notice also that the lower() function in sqlite doesn't work on non-ASCII characters - but again those are probably the ones that you are already replacing!

    The function also replaces both GLOB wildcards, * and ?, with "escaped" versions.

提交回复
热议问题