SQLite unicode 斯拉夫重音词 Android

Posted

技术标签:

【中文标题】SQLite unicode 斯拉夫重音词 Android【英文标题】:SQLite unicode slavic accented words Android 【发布时间】:2014-11-07 20:03:14 【问题描述】:

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

如果我尝试选择 LOWER(title),我总是会返回相同的值“Ž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: 我决定通过更改选择查询中的数据来直接处理这个问题。虽然这不适用于所有情况(我必须涵盖所有口音),但它现在适合我的情况。所以我把它贴出来:

-- 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("[^\\pASCII]", "");

【问题讨论】:

【参考方案1】:

点赞never uses a custom collation。

FTS 可以use a custom tokenizer,但您必须检查unicode61 是否适用于您要支持的所有android 版本。


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

【讨论】:

可能自定义标记器是不可能的,因为据我了解 Android 没有太多支持。此外,我还必须考虑旧版本的 Android(2.3),因此标准化可能是这里的最佳选择。我已经做了一个丑陋的黑客来处理这个问题,但很高兴了解规范化。将报告解决方案是否成功。我也发现了类似的东西:***.com/questions/16282083/…

以上是关于SQLite unicode 斯拉夫重音词 Android的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql 对非重音不敏感,对重音词敏感

unicode排序规则,汉字怎么区分大小写,区分重音,区分假名,区分宽度

PyYaml - 使用特殊字符(即重音符号)转储 unicode

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

如何在 Sqlite 中实现重音/变音符号不敏感搜索? [复制]

如何使用正则表达式避免在 unicode 重音后大写字母 [重复]