为什么Telegram不能搜寻中文讯息

Telegram对于中文的支持并不很好,尤其是搜寻功能遇上汉字即与残废无异。。,原因究竟是什么呢??让我们来逐步抽丝剥茧吧

首先,我们看看Telegram核心td-lib是如何存储消息的。这是MessagesDb.cpp,从12到14行我们可以知道Telegram使用SQLite作为资料库:

#include“ td / db / SqliteConnectionSafe.h” 
#include“ td / db / SqliteDb.h” 
#include“ td / db / SqliteStatement.h”

接下来,我们可以发现这个数据库中有很多表,但是我们只关心messages_fts 这个虚拟表。那么,这个fts又是什么呢??

如果不存在,则创建虚拟表使用fts5的messages_fts(文本,content ='messages',content_rowid ='search_id',tokenize =“ unicode61 remove_diacritics 0 tokenchars'\ a'”)

原来,fts实际上全文搜索,也就是所谓的全文搜索,而fts5则是SQLite内建可以提供全文搜索的模组。

说到这里,来先打个岔谈谈字串搜寻。在高中演算法竞赛中,除了朴素的暴力解外,最常见而广为人知的方法有两种:KMP演算法与其他基于散列的演算法。前者是由资讯界史诗级教授Donald E. Knuth及Pratt,莫里斯于1977年提出。

而SQLite fts5比较类似基于hash的演算法,他的做法大约如下:

  1. 将字串以tokenizer切割成一段段的短语
  2. phrase进行hash后存进表
  3. 搜寻时也将搜寻字串以tokenizer切割成一段段的短语,在哈希表中进行搜寻

举例而言,讯息qwert qaz qsc在搜寻时只会分别匹配到qwert, ,这qaz三个qsc字串,你搜寻单独的qaer都不会匹配到。

为什么Telegram不能搜寻中文讯息

讯息内容

为什么Telegram不能搜寻中文讯息

搜寻一个阶段,成功

为什么Telegram不能搜寻中文讯息

搜寻单独q,反而失败

那问题接着来了:标记生成器根据什么切割??用以切割阶段的字元,我们称之分离器分隔符,而剩下构成的字元称之令牌。进一步来说,依据的unicode的类别,属于大号*(字母)N *(数字)Co(其他)预设为令牌,其余都被视为分隔符

因此,我们终于找到Telegram不能搜寻中文讯息的根本原因了。原来,由于unicode CJK(中日韩表意文字)绝大部分都属于Lo类别,从而,汉字语汉字间没有任何分隔符,会被整串拿去哈希,从而导致搜寻无效。

为什么Telegram不能搜寻中文讯息

为什么Telegram不能搜寻中文讯息

搜寻整串CJK即成功,证实我们的推论

结语

不小心就打了一堆堆废话呢,相信大家都知道Telegram不能搜寻中文讯息的原因了。解决的方法我有想到两种,其一是手动在汉字间插入不可见的分隔符,另一种是写个客制化的tokenizer

于此将我的一点浅见拿来分享作为抛砖引玉,希望各位电神不吝指教。未来若有空我也十分希望能为Telegram社群贡献。

原文地址:https://medium.com/@nevik.w39/%E7%82%BA%E4%BB%80%E9%BA%BC-telegram-%E4%B8%8D%E8%83%BD%E6%90%9C%E5%B0%8B%E4%B8%AD%E6%96%87%E8%A8%8A%E6%81%AF-6b7d07690e6f

实用技巧

苹果开放了 iPhone 有锁机 ICCID 完美激活方式

2020-3-11 16:52:45

实用技巧

Realm:一个基于 Rust 的全新流量转发工具

2020-5-14 18:22:20

3 条回复 A文章作者 M管理员
  1. 喵哩喵哩

    试试

  2. 有下载nicegram的方法吗 兄弟

  3. 第一步 点击右上角的放大镜 然后输入 @zwdhqun 去搜索 第二步 点击显示的第一个搜 然后再点击 Join 按提示完成验证进群 第三步 发送中文包 三个字 到群内,然后点击机器人回复的第一个 中文包 这个三个字 注意不需要下载 让你下载的都是病毒 第四步 选择频道推荐的最佳中文包 点击一下蓝色的链接 第五步 点击弹窗的 CHANGE 就成功切换到中文了 频道内的这些中文包都是完成度比较高的。

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索