SQLite unicode slavic重音词Android

时间:2014-09-13 23:19:15

标签: android sqlite unicode full-text-search

如果用户在本地数据库中搜索重音词,我会尝试过滤掉重音词。但我有问题,即用斯拉夫字母ČŠŽ。在我的SQLite数据库中,我有一个字段“title”,其值为:“Želodček”

如果我尝试选择LOWER(标题),我总会得到相同的值“Želodček”,而其他单词正确地降低了。只有当这个词以ČŽŠ开头时,它才会得到更低的限制。这只会出现带有重音字母的单词。

数据库记录

Stomach
Želodček

大写与UPPER()

STOMACH
ŽELODčEK

小写与LOWER()

stomach
Želodček

我已经尝试使用setLocale()设置本地化而没有运气。我也尝试了不同的排序规则,如NOCASE,UNICODE,LOCALIZED,但没有任何效果。我想知道为什么当较低的情况下,第一个字母不是较低的套管,而上部套管的其他重音字是小写的。

我已经用LIKE搜索解决了问题,我用他们较低的对应词替换重音词。但是我对全文(FTS3)搜索有问题,因为我不能在MATCH中使用相同的技巧。

 -- works but it's a hack
 SELECT title FROM articles WHERE REPLACE(LOWER(title),'Ž','ž') LIKE '%želodček%'
 -- can't seem to get it work
 SELECT title FROM articles WHERE title MATCH 'želodček' COLLATE NOCASE 

有没有解决方案或存在更大的问题?

更新 还没有最佳解决方案。

非最佳解决方案1: 我决定通过更改select查询中的数据来直接处理问题。虽然这不适用于所有情况(我必须涵盖所有口音),但它现在适合我的情况。所以我发布了它:

-- LIKE query
SELECT title FROM articles WHERE (REPLACE(REPLACE(REPLACE(LOWER(title),'Č','č'),'Š','š'),'Ž','ž') LIKE ? COLLATE NOCASE))

-- MATCH query (FTS)
-- In this case I programmatically replace searched word with 2 word variation (one that starts with lowercase and one that starts with uppercase) ie: title='želodček OR Želodček'
SELECT title FROM articles WHERE title MATCH ? COLLATE UNICODE

非最佳解决方案2: 正如用户CL所建议的那样。以标准化形式插入(对我来说不起作用,因为标准化形式基本上是原始的unicode形式)。我更进一步,插入标题剥离的重音符号(基本上是ASCII形式)。这可能比一般解决方案中的解决方案更好。因为我只覆盖了第一个口音。 但也有缺点:

  • 数据加倍(一个unicode标题和一个ASCII标题)。如果您有大量数据,这可能是个问题。
  • 不支持某些字符(正常化和剥离后中文字符将会消失)
  • 通过剥离重音获得的歧义(即两个词“zelo”和“želo”具有不同的含义,但在搜索时都会出现)。

以下是它的Java代码:

// Gets you the ASCII version of unicode title which you insert into different column
String titleAsciiName = Normalizer.normalize(title, Normalizer.Form.NFD)
    .replaceAll("[^\\p{ASCII}]", "");

1 个答案:

答案 0 :(得分:0)

LIKE never uses a custom collation

FTS可use a custom tokenizer,但你必须检查unicode61是否适用于你想支持的所有Android版本。


Android数据库API不允许创建LIKE或FTS标记化程序的自定义实现。 您可能希望在数据库中存储字符串的规范化版本。