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的主要内容,如果未能解决你的问题,请参考以下文章
unicode排序规则,汉字怎么区分大小写,区分重音,区分假名,区分宽度
PyYaml - 使用特殊字符(即重音符号)转储 unicode