私はAndroidの初心者で、SQLiteでクエリに取り組んでいます。私の問題は、文字列でアクセントを使用する場合です。
私が行った場合:
SELECT * FROM TB_MOVIE WHERE MOVIE_NAME LIKE '%a%' ORDER BY MOVIE_NAME;
それは戻ります:
しかし、私がそうするなら:
SELECT * FROM TB_MOVIE WHERE MOVIE_NAME LIKE '%à%' ORDER BY MOVIE_NAME;
それは戻ります:
アクセントや大文字小文字を気にせずにSQLiteDBで文字列を選択したい。助けてください。
一般に、SQLでの文字列の比較は、列または式のCOLLATE
ルールによって制御されます。 Androidでは、3つの照合シーケンスのみが 事前定義 :BINARY(デフォルト)、LOCALIZED、およびUNICODEです。それらのどれもあなたのユースケースに理想的ではなく、新しい照合関数をインストールするためのC APIは、残念ながらJava APIでは公開されていません。
これを回避するには:
MOVIE_NAME_ASCII
アクセント記号を削除して、この列に値を格納します。文字列をUnicodeNormal Form D(NFD)に正規化し、非ASCIIコードポイントを削除することでアクセントを削除できます。NFDはアクセント付き文字を大まかにプレーンとして表すためASCII +アクセントマーカーの組み合わせ:
String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
.replaceAll("[^\\p{ASCII}]", "");
このASCII正規化列でテキスト検索を実行しますが、元のUnicode列のデータを表示します。
Android sqlite、LIKE
and GLOB
では_COLLATE LOCALIZED
_と_COLLATE 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("?", "[?]");
}
_
そして(もちろん、文字通りこのようではありません):
_SELECT * from table WHERE lower(column) GLOB "*addTildeOptions(searchText)*"
_
このように、たとえばスペイン語では、ユーザーはmasまたはmásのいずれかを検索します-)は検索をm [aáàäâã] sに変換し、両方の結果を返します。
GLOB
は_COLLATE NOCASE
_を無視することに注意することが重要です。そのため、関数とクエリの両方ですべてを小文字に変換しました。 sqliteのlower()
関数は非ASCII文字では機能しないことにも注意してください。ただし、これらはおそらくすでに置き換えているものです。
この関数は、GLOB
ワイルドカード_*
_と_?
_の両方を「エスケープされた」バージョンに置き換えます。
Android NDKを使用して、目的のICU(Unicodeの国際コンポーネント)を含むSQLiteソースを再コンパイルできます。ここでロシア語で説明されています: http: //habrahabr.ru/post/122408/
ICUを使用してソースを使用してSQLilteをコンパイルするプロセスは次のとおりです。
残念ながら、CPUごとに異なるAPKが作成されることになります。