日常更新; close #198
This commit is contained in:
parent
bfeb35dccb
commit
f1c6b9a47e
@ -30,7 +30,7 @@
|
||||
# 降低一些几乎只在一个固定词汇中使用的读音的权重,不让其参与注音,在 base 中手动注音。
|
||||
---
|
||||
name: 8105
|
||||
version: "2023-04-11"
|
||||
version: "2023-04-13"
|
||||
sort: by_weight
|
||||
...
|
||||
### 按需启用
|
||||
@ -46,6 +46,7 @@ sort: by_weight
|
||||
嬢 niang 1
|
||||
薙 ti 1
|
||||
菈 la 1
|
||||
卻 que 1
|
||||
# 注释掉的这几行已经加入到下面并调整到合适的权重了
|
||||
# 〇 ling
|
||||
# 囧 jiong
|
||||
@ -1600,7 +1601,7 @@ sort: by_weight
|
||||
墦 fan 13
|
||||
𫔍 fan 0
|
||||
𬸪 fan 0
|
||||
放 fang 1730745
|
||||
放 fang 7730745
|
||||
房 fang 980289
|
||||
防 fang 406226
|
||||
方 fang 347176
|
||||
|
26930
cn_dicts/base.dict.yaml
26930
cn_dicts/base.dict.yaml
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
||||
#
|
||||
#
|
||||
# 只保留三个字及以上的
|
||||
# 与 base sogou 没有重复
|
||||
# 与 base 没有重复
|
||||
#
|
||||
#
|
||||
# - 日常用语
|
||||
@ -17,7 +17,7 @@
|
||||
# - [同义词词林2020.3.26修订版](https://forum.freemdict.com/t/topic/1211)
|
||||
---
|
||||
name: ext
|
||||
version: "2023-04-11"
|
||||
version: "2023-04-13"
|
||||
sort: by_weight
|
||||
columns:
|
||||
- text
|
||||
@ -3653,6 +3653,7 @@ columns:
|
||||
一般原则 100
|
||||
一般啦 100
|
||||
一般在 100
|
||||
一般多少斤 100
|
||||
一般官员 100
|
||||
一般巨人 100
|
||||
一般常识 100
|
||||
@ -10185,9 +10186,6 @@ columns:
|
||||
不习惯似的 100
|
||||
不了不了 100
|
||||
不了之局 100
|
||||
不了了之了 100
|
||||
不了了之啊 100
|
||||
不了了当 100
|
||||
不了啊 100
|
||||
不了汉 100
|
||||
不予理会 100
|
||||
@ -18774,7 +18772,6 @@ columns:
|
||||
了不起的 100
|
||||
了不起的盖茨比 100
|
||||
了个寂寞 100
|
||||
了了于心 100
|
||||
了事环 100
|
||||
了你的 100
|
||||
了几分 100
|
||||
@ -26074,6 +26071,7 @@ columns:
|
||||
以一警百 100
|
||||
以一驭万 100
|
||||
以上的 100
|
||||
以下几处 100
|
||||
以下几种 100
|
||||
以下几种可能 100
|
||||
以下开放 100
|
||||
@ -29607,6 +29605,7 @@ columns:
|
||||
你看看人家 100
|
||||
你看看你看看 100
|
||||
你看着他 100
|
||||
你看着办 100
|
||||
你看行不行 100
|
||||
你看谁来 100
|
||||
你看谁来了 100
|
||||
@ -32279,7 +32278,6 @@ columns:
|
||||
光之所向 100
|
||||
光之祝福 100
|
||||
光乎乎 100
|
||||
光了了 100
|
||||
光二极管 100
|
||||
光亮亮 100
|
||||
光伏器件 100
|
||||
@ -32991,6 +32989,7 @@ columns:
|
||||
全都去死 100
|
||||
全都去死吧 100
|
||||
全都向 100
|
||||
全都对 100
|
||||
全都想 100
|
||||
全都搞定 100
|
||||
全都搞定了 100
|
||||
@ -38339,6 +38338,7 @@ columns:
|
||||
养蜂业 100
|
||||
养蜂人 100
|
||||
养蜗牛 100
|
||||
养词库 100
|
||||
养起来 100
|
||||
养身之道 100
|
||||
养身体 100
|
||||
@ -38844,6 +38844,7 @@ columns:
|
||||
写在纸上 100
|
||||
写在脸上 100
|
||||
写在脸上了 100
|
||||
写在这里 100
|
||||
写多少了 100
|
||||
写好了吗 100
|
||||
写完一本 100
|
||||
@ -39565,6 +39566,7 @@ columns:
|
||||
准备好了吗 100
|
||||
准备好了没有 100
|
||||
准备好的 100
|
||||
准备导入 100
|
||||
准备干什么 100
|
||||
准备年货 100
|
||||
准备很齐 100
|
||||
@ -41866,7 +41868,6 @@ columns:
|
||||
刮龙卷风 100
|
||||
到一百零八岁 100
|
||||
到上海了 100
|
||||
到不了了 100
|
||||
到中间 100
|
||||
到中间儿 100
|
||||
到了另一边 100
|
||||
@ -42972,7 +42973,6 @@ columns:
|
||||
动一下手脚 100
|
||||
动一动了 100
|
||||
动下手脚 100
|
||||
动不了了 100
|
||||
动不动就想 100
|
||||
动不动就要 100
|
||||
动不动工 100
|
||||
@ -46277,6 +46277,7 @@ columns:
|
||||
厨房里 100
|
||||
厨神下凡 100
|
||||
厨神争霸 100
|
||||
去上坟 100
|
||||
去上班 100
|
||||
去不去不 100
|
||||
去不去啊 100
|
||||
@ -46313,6 +46314,7 @@ columns:
|
||||
去创造 100
|
||||
去前缀 100
|
||||
去医院检查 100
|
||||
去南站 100
|
||||
去厕所 100
|
||||
去厕所了 100
|
||||
去取之间 100
|
||||
@ -46326,6 +46328,8 @@ columns:
|
||||
去吗去吗 100
|
||||
去吧少年 100
|
||||
去听听吧 100
|
||||
去哪个区 100
|
||||
去哪个学校 100
|
||||
去哪儿啊 100
|
||||
去哪儿玩 100
|
||||
去哪儿玩儿 100
|
||||
@ -46338,6 +46342,8 @@ columns:
|
||||
去国外 100
|
||||
去外面 100
|
||||
去大理 100
|
||||
去大街上 100
|
||||
去娘家 100
|
||||
去嫖娼 100
|
||||
去学校 100
|
||||
去对付 100
|
||||
@ -46351,10 +46357,14 @@ columns:
|
||||
去年买了个 100
|
||||
去年买了个表 100
|
||||
去年分数线 100
|
||||
去年差不多 100
|
||||
去年底啊 100
|
||||
去年是 100
|
||||
去年疫情 100
|
||||
去年的 100
|
||||
去年还是前年 100
|
||||
去年这个时候 100
|
||||
去年这时候 100
|
||||
去广告插件 100
|
||||
去彼取此 100
|
||||
去得太晚 100
|
||||
@ -46372,6 +46382,7 @@ columns:
|
||||
去我家睡 100
|
||||
去打劫 100
|
||||
去打暑假工 100
|
||||
去扫墓 100
|
||||
去扭转天亮 100
|
||||
去找你的 100
|
||||
去找到了 100
|
||||
@ -46383,16 +46394,21 @@ columns:
|
||||
去挣钱 100
|
||||
去换取 100
|
||||
去捣乱 100
|
||||
去掉一个 100
|
||||
去掉注音 100
|
||||
去插眼 100
|
||||
去放弃 100
|
||||
去救援 100
|
||||
去日本 100
|
||||
去暗投明 100
|
||||
去月球 100
|
||||
去杀胜残 100
|
||||
去杂去劣 100
|
||||
去染头发 100
|
||||
去查一下 100
|
||||
去查查 100
|
||||
去查查吧 100
|
||||
去楼顶 100
|
||||
去歌唱 100
|
||||
去死去死 100
|
||||
去死吧你啊 100
|
||||
@ -46424,6 +46440,7 @@ columns:
|
||||
去看了吗 100
|
||||
去看店 100
|
||||
去看烟花 100
|
||||
去看直播 100
|
||||
去看看 100
|
||||
去看看呗 100
|
||||
去睡了 100
|
||||
@ -46451,6 +46468,7 @@ columns:
|
||||
去谁的家 100
|
||||
去走亲戚 100
|
||||
去超越 100
|
||||
去跨年 100
|
||||
去辩解 100
|
||||
去迟一步 100
|
||||
去送死 100
|
||||
@ -46470,6 +46488,7 @@ columns:
|
||||
去问问吧 100
|
||||
去阻截 100
|
||||
去阻挠 100
|
||||
去领证 100
|
||||
去领钱 100
|
||||
去食堂 100
|
||||
去食堂打饭 100
|
||||
@ -49607,7 +49626,6 @@ columns:
|
||||
吃不下了 100
|
||||
吃不下去 100
|
||||
吃不习惯 100
|
||||
吃不了了 100
|
||||
吃不了苦 100
|
||||
吃不出啊 100
|
||||
吃不出来 100
|
||||
@ -49942,6 +49960,7 @@ columns:
|
||||
各拉丹冬峰 100
|
||||
各搞各的 100
|
||||
各方势力 100
|
||||
各方案 100
|
||||
各方满意 100
|
||||
各方瞩目 100
|
||||
各显所长 100
|
||||
@ -52219,6 +52238,7 @@ columns:
|
||||
咱公司 100
|
||||
咱又不是 100
|
||||
咱啥时候 100
|
||||
咱就是 100
|
||||
咱是不是 100
|
||||
咱爸咱妈 100
|
||||
咳了一声 100
|
||||
@ -53064,6 +53084,7 @@ columns:
|
||||
啥事情都能用 100
|
||||
啥劲头 100
|
||||
啥啥啥 100
|
||||
啥地步 100
|
||||
啥家庭 100
|
||||
啥建议 100
|
||||
啥当啥立 100
|
||||
@ -53351,7 +53372,6 @@ columns:
|
||||
喝不上 100
|
||||
喝不下 100
|
||||
喝不下去 100
|
||||
喝不了了 100
|
||||
喝不动 100
|
||||
喝不动了 100
|
||||
喝不喝茶 100
|
||||
@ -56664,6 +56684,7 @@ columns:
|
||||
国家火山公园 100
|
||||
国家电力监管委员会 100
|
||||
国家的 100
|
||||
国家监委 100
|
||||
国家科学委员会 100
|
||||
国家积累 100
|
||||
国家税务局 100
|
||||
@ -59778,8 +59799,6 @@ columns:
|
||||
大借款 100
|
||||
大停电 100
|
||||
大傻叉 100
|
||||
大傻屄 100
|
||||
大傻逼 100
|
||||
大元大一统志 100
|
||||
大兄弟呀 100
|
||||
大兄弟啊 100
|
||||
@ -60929,7 +60948,6 @@ columns:
|
||||
天公不做美 100
|
||||
天其实并不高 100
|
||||
天冬苯丙二肽酯 100
|
||||
天冷了了 100
|
||||
天凉了 100
|
||||
天凉好个秋 100
|
||||
天凤对战平台 100
|
||||
@ -62743,7 +62761,6 @@ columns:
|
||||
好一片 100
|
||||
好一阵儿 100
|
||||
好上好下 100
|
||||
好不了了 100
|
||||
好不到哪儿去 100
|
||||
好不到哪去 100
|
||||
好不好使 100
|
||||
@ -64205,6 +64222,7 @@ columns:
|
||||
字字珠玉 100
|
||||
字幕文件 100
|
||||
字形输入法 100
|
||||
字或词 100
|
||||
字打错了 100
|
||||
字根合体字 100
|
||||
字根通用码 100
|
||||
@ -66933,7 +66951,6 @@ columns:
|
||||
小斯韵 100
|
||||
小旋风 100
|
||||
小无相功 100
|
||||
小时了了大未必佳 100
|
||||
小时代 100
|
||||
小时代系列 100
|
||||
小时候儿 100
|
||||
@ -72137,6 +72154,7 @@ columns:
|
||||
开房记录 100
|
||||
开挂了吗 100
|
||||
开挂吗 100
|
||||
开摆了 100
|
||||
开放三胎 100
|
||||
开放下载 100
|
||||
开放与躺平 100
|
||||
@ -73815,7 +73833,6 @@ columns:
|
||||
待下去 100
|
||||
待不下去了 100
|
||||
待不了 100
|
||||
待不了了 100
|
||||
待久了 100
|
||||
待了一会儿 100
|
||||
待了一天 100
|
||||
@ -75285,7 +75302,6 @@ columns:
|
||||
志足意满 100
|
||||
志骄意满 100
|
||||
志高气扬 100
|
||||
忘不了了 100
|
||||
忘不了餐厅 100
|
||||
忘不掉啊 100
|
||||
忘了原来的方向 100
|
||||
@ -78316,7 +78332,6 @@ columns:
|
||||
我上班去了 100
|
||||
我上课去了 100
|
||||
我上课啦 100
|
||||
我下了了 100
|
||||
我下了哦 100
|
||||
我下午回家 100
|
||||
我下咯 100
|
||||
@ -79025,7 +79040,6 @@ columns:
|
||||
我去上班了 100
|
||||
我去上课了 100
|
||||
我去不了 100
|
||||
我去不了了 100
|
||||
我去不可 100
|
||||
我去你别劝 100
|
||||
我去你加 100
|
||||
@ -79076,7 +79090,6 @@ columns:
|
||||
我发过去 100
|
||||
我发过去了 100
|
||||
我发过来 100
|
||||
我受不了了 100
|
||||
我受不可 100
|
||||
我只不过是在 100
|
||||
我只发现 100
|
||||
@ -80386,7 +80399,9 @@ columns:
|
||||
我看看你啊 100
|
||||
我看看吧 100
|
||||
我看看啊 100
|
||||
我看着办 100
|
||||
我看行哦 100
|
||||
我看行啊 100
|
||||
我看还是 100
|
||||
我看金庸 100
|
||||
我真不是 100
|
||||
@ -80660,6 +80675,8 @@ columns:
|
||||
我试一试 100
|
||||
我试一试啊 100
|
||||
我试了 100
|
||||
我试了是可以 100
|
||||
我试了是可以的 100
|
||||
我试试吧 100
|
||||
我试试啊 100
|
||||
我试过了 100
|
||||
@ -81790,7 +81807,6 @@ columns:
|
||||
打下一个江山 100
|
||||
打不下 100
|
||||
打不下的 100
|
||||
打不了了 100
|
||||
打不了的 100
|
||||
打不到车 100
|
||||
打不动 100
|
||||
@ -85752,7 +85768,6 @@ columns:
|
||||
接到旨意 100
|
||||
接到过 100
|
||||
接到过的 100
|
||||
接受不了了 100
|
||||
接受吗 100
|
||||
接受啊 100
|
||||
接受器 100
|
||||
@ -86349,6 +86364,7 @@ columns:
|
||||
搞得快把 100
|
||||
搞得快跟 100
|
||||
搞得过 100
|
||||
搞忘了 100
|
||||
搞成这样 100
|
||||
搞把戏 100
|
||||
搞歧视 100
|
||||
@ -87148,7 +87164,6 @@ columns:
|
||||
攸攸之口 100
|
||||
改一个 100
|
||||
改一点 100
|
||||
改不了了 100
|
||||
改不过来 100
|
||||
改个名 100
|
||||
改个密码 100
|
||||
@ -88635,6 +88650,7 @@ columns:
|
||||
新农合 100
|
||||
新冠后遗症 100
|
||||
新冠治疗 100
|
||||
新冠溯源 100
|
||||
新冠病毒感染 100
|
||||
新冠症状 100
|
||||
新冷战 100
|
||||
@ -89446,6 +89462,7 @@ columns:
|
||||
无损伤动脉止血钳 100
|
||||
无损音乐 100
|
||||
无支祁 100
|
||||
无改动 100
|
||||
无敌不克 100
|
||||
无敌了 100
|
||||
无敌啦 100
|
||||
@ -90614,6 +90631,8 @@ columns:
|
||||
明摆着的 100
|
||||
明教教主 100
|
||||
明文上传 100
|
||||
明文存储 100
|
||||
明文存储密码 100
|
||||
明断是非 100
|
||||
明新工专 100
|
||||
明日就到 100
|
||||
@ -98616,6 +98635,7 @@ columns:
|
||||
正在探路 100
|
||||
正在收看 100
|
||||
正在收看的是 100
|
||||
正在改 100
|
||||
正在施法 100
|
||||
正在核实 100
|
||||
正在死亡 100
|
||||
@ -102145,6 +102165,7 @@ columns:
|
||||
没有默契 100
|
||||
没权力 100
|
||||
没权没势 100
|
||||
没权重 100
|
||||
没来历 100
|
||||
没来回 100
|
||||
没来得 100
|
||||
@ -102162,6 +102183,7 @@ columns:
|
||||
没水平 100
|
||||
没没无闻 100
|
||||
没沾过血 100
|
||||
没泄漏 100
|
||||
没洗干净 100
|
||||
没流量 100
|
||||
没流量了 100
|
||||
@ -103414,7 +103436,6 @@ columns:
|
||||
洲际飞弹 100
|
||||
活下来的 100
|
||||
活不下去了 100
|
||||
活不了了 100
|
||||
活不活 100
|
||||
活不活泼 100
|
||||
活不起 100
|
||||
@ -108313,6 +108334,7 @@ columns:
|
||||
猪刚鬣 100
|
||||
猪圈里 100
|
||||
猪圈里的猪 100
|
||||
猪圈里的猪啊 100
|
||||
猪太郎 100
|
||||
猪头一个 100
|
||||
猪头人 100
|
||||
@ -108859,7 +108881,6 @@ columns:
|
||||
玩三国杀 100
|
||||
玩下去 100
|
||||
玩不下去 100
|
||||
玩不了了 100
|
||||
玩不动 100
|
||||
玩不我就 100
|
||||
玩不明白 100
|
||||
@ -108918,6 +108939,7 @@ columns:
|
||||
玩儿命啊 100
|
||||
玩儿命追 100
|
||||
玩儿啊 100
|
||||
玩儿完了 100
|
||||
玩儿家 100
|
||||
玩儿得转 100
|
||||
玩儿死你 100
|
||||
@ -108952,7 +108974,9 @@ columns:
|
||||
玩失踪 100
|
||||
玩它一会 100
|
||||
玩它一会儿 100
|
||||
玩完了 100
|
||||
玩完了吗 100
|
||||
玩完了啊 100
|
||||
玩客币 100
|
||||
玩家一号 100
|
||||
玩家网 100
|
||||
@ -111223,7 +111247,6 @@ columns:
|
||||
白丝黑丝 100
|
||||
白中发 100
|
||||
白举铁 100
|
||||
白了了 100
|
||||
白了头 100
|
||||
白事红事 100
|
||||
白云之上 100
|
||||
@ -113922,7 +113945,6 @@ columns:
|
||||
睡上去 100
|
||||
睡上来 100
|
||||
睡下来 100
|
||||
睡不了了 100
|
||||
睡不好觉 100
|
||||
睡不着啊 100
|
||||
睡个好觉 100
|
||||
@ -114768,6 +114790,7 @@ columns:
|
||||
确认我 100
|
||||
确认我不是 100
|
||||
确认收货 100
|
||||
确认收货后 100
|
||||
确认框 100
|
||||
确认的 100
|
||||
确认这一点 100
|
||||
@ -116480,6 +116503,8 @@ columns:
|
||||
穿山鼠 100
|
||||
穿得太多了 100
|
||||
穿得少了 100
|
||||
穿得漂亮点 100
|
||||
穿得漂亮点儿 100
|
||||
穿得非常 100
|
||||
穿搭秀 100
|
||||
穿搭达人 100
|
||||
@ -116612,9 +116637,11 @@ columns:
|
||||
窦公训女 100
|
||||
窦太后 100
|
||||
窿缘桉 100
|
||||
立一个规矩 100
|
||||
立不世之功 100
|
||||
立不住脚 100
|
||||
立个碑 100
|
||||
立个规矩 100
|
||||
立为太子 100
|
||||
立为皇太子 100
|
||||
立了不少功劳 100
|
||||
@ -116726,6 +116753,7 @@ columns:
|
||||
竖起脊梁 100
|
||||
竖起自然 100
|
||||
竖鸡蛋 100
|
||||
站个人 100
|
||||
站了很久 100
|
||||
站住别跑 100
|
||||
站内信 100
|
||||
@ -117218,7 +117246,6 @@ columns:
|
||||
等下回 100
|
||||
等下回我 100
|
||||
等下我把 100
|
||||
等不了了 100
|
||||
等不住 100
|
||||
等不住想要 100
|
||||
等不到的爱 100
|
||||
@ -117608,7 +117635,6 @@ columns:
|
||||
算谁的 100
|
||||
算进来 100
|
||||
箜篌指尖唱 100
|
||||
管不了了是吧 100
|
||||
管不了你 100
|
||||
管不了你了 100
|
||||
管不了你了是吧 100
|
||||
@ -127868,6 +127894,7 @@ columns:
|
||||
裒多益寡 100
|
||||
裒敛无厌 100
|
||||
裕后街 100
|
||||
裕泰茶馆 100
|
||||
裕溪河 100
|
||||
裕隆牌 100
|
||||
裘佳宁 100
|
||||
@ -128205,6 +128232,7 @@ columns:
|
||||
要了你的命 100
|
||||
要了小命 100
|
||||
要争气 100
|
||||
要交学费 100
|
||||
要亮得多 100
|
||||
要人保管 100
|
||||
要从此路过 100
|
||||
@ -128240,8 +128268,10 @@ columns:
|
||||
要压岁钱 100
|
||||
要去哪 100
|
||||
要去哪儿 100
|
||||
要去哪玩 100
|
||||
要去哪里 100
|
||||
要去哪里呀 100
|
||||
要去超市 100
|
||||
要参加吗 100
|
||||
要及时 100
|
||||
要发就发 100
|
||||
@ -128283,6 +128313,7 @@ columns:
|
||||
要小写吗 100
|
||||
要尝试 100
|
||||
要尝试着 100
|
||||
要居家 100
|
||||
要带什么 100
|
||||
要带着你 100
|
||||
要带着你远走 100
|
||||
@ -128290,10 +128321,14 @@ columns:
|
||||
要帮忙 100
|
||||
要帮忙不 100
|
||||
要干了 100
|
||||
要开了 100
|
||||
要开学了 100
|
||||
要开工 100
|
||||
要开开心心 100
|
||||
要开心点 100
|
||||
要开摄像头 100
|
||||
要开服 100
|
||||
要开空调 100
|
||||
要开黑 100
|
||||
要弄明白 100
|
||||
要往哪里去 100
|
||||
@ -128331,6 +128366,7 @@ columns:
|
||||
要拿姑娘与它比模样 100
|
||||
要指定 100
|
||||
要换宿舍 100
|
||||
要接送 100
|
||||
要插入 100
|
||||
要撑住 100
|
||||
要改改吗 100
|
||||
@ -128398,6 +128434,7 @@ columns:
|
||||
要看的书 100
|
||||
要睡了嘛 100
|
||||
要矜持 100
|
||||
要竞选 100
|
||||
要答应我 100
|
||||
要紧事 100
|
||||
要紧事儿 100
|
||||
@ -128421,6 +128458,8 @@ columns:
|
||||
要补课 100
|
||||
要被打 100
|
||||
要要要 100
|
||||
要解封 100
|
||||
要解锁 100
|
||||
要言不繁 100
|
||||
要言之 100
|
||||
要让你 100
|
||||
@ -128444,6 +128483,7 @@ columns:
|
||||
要这么做 100
|
||||
要这样设计 100
|
||||
要进宫 100
|
||||
要进攻 100
|
||||
要连任了 100
|
||||
要追上 100
|
||||
要退赛 100
|
||||
@ -128460,6 +128500,7 @@ columns:
|
||||
要问你 100
|
||||
要闹哪儿样 100
|
||||
要闹哪样 100
|
||||
要降温 100
|
||||
要难一些 100
|
||||
要靠自己 100
|
||||
要顺台阶而上 100
|
||||
@ -129644,7 +129685,6 @@ columns:
|
||||
访法之旅 100
|
||||
访美之旅 100
|
||||
访英之旅 100
|
||||
访问不了了 100
|
||||
访问凭证 100
|
||||
访问凭证信息 100
|
||||
访问异常 100
|
||||
@ -129843,6 +129883,7 @@ columns:
|
||||
试试看呐 100
|
||||
试试这个 100
|
||||
试起来 100
|
||||
试过了吗 100
|
||||
试都不想试 100
|
||||
试错性 100
|
||||
试镜室 100
|
||||
@ -132516,7 +132557,6 @@ columns:
|
||||
走上人生巅峰 100
|
||||
走下流程 100
|
||||
走不下去 100
|
||||
走不了了 100
|
||||
走不出去 100
|
||||
走不走啊 100
|
||||
走不通 100
|
||||
@ -133350,7 +133390,6 @@ columns:
|
||||
跌进来 100
|
||||
跑一下 100
|
||||
跑上跑下 100
|
||||
跑不了了 100
|
||||
跑不了寺 100
|
||||
跑不了庙 100
|
||||
跑不动了 100
|
||||
@ -136045,6 +136084,7 @@ columns:
|
||||
这两个词 100
|
||||
这两件事 100
|
||||
这两兄弟 100
|
||||
这两处 100
|
||||
这两款 100
|
||||
这两者的区别 100
|
||||
这两行 100
|
||||
@ -137923,8 +137963,6 @@ columns:
|
||||
选举罢免法 100
|
||||
选举署 100
|
||||
选举资格 100
|
||||
选了了放弃 100
|
||||
选了放弃了 100
|
||||
选亚索 100
|
||||
选什么 100
|
||||
选优淘劣 100
|
||||
@ -138655,6 +138693,8 @@ columns:
|
||||
避风台 100
|
||||
避风处 100
|
||||
邀天之幸 100
|
||||
邀请一个人 100
|
||||
邀请别人 100
|
||||
邀请回答 100
|
||||
邀请我 100
|
||||
邀请我们 100
|
||||
@ -140287,7 +140327,6 @@ columns:
|
||||
都逼成什么样了 100
|
||||
都那么 100
|
||||
都铎王朝 100
|
||||
都错了 100
|
||||
都阳了 100
|
||||
都阻止不了 100
|
||||
都难以 100
|
||||
@ -142497,6 +142536,7 @@ columns:
|
||||
问安者 100
|
||||
问就是 100
|
||||
问张昭 100
|
||||
问得不好 100
|
||||
问得奇怪 100
|
||||
问我妈 100
|
||||
问我干嘛 100
|
||||
@ -143239,6 +143279,8 @@ columns:
|
||||
阿法尔沙漠 100
|
||||
阿法狗 100
|
||||
阿法罗密欧 100
|
||||
阿波尼亚 100
|
||||
阿波连 100
|
||||
阿泰包子 100
|
||||
阿泰斯特 100
|
||||
阿滋海默症 100
|
||||
@ -147464,6 +147506,7 @@ columns:
|
||||
骂一句 100
|
||||
骂了一顿 100
|
||||
骂你了 100
|
||||
骂傻逼 100
|
||||
骂出来 100
|
||||
骂别人 100
|
||||
骂我干嘛 100
|
||||
@ -148038,6 +148081,7 @@ columns:
|
||||
高钧贤 100
|
||||
高铁侠 100
|
||||
高铁币 100
|
||||
高铁战士 100
|
||||
高铁晚点 100
|
||||
高铁票 100
|
||||
高长虹 100
|
||||
|
@ -9,10 +9,10 @@
|
||||
# [腾讯词向量百万词库](https://ai.tencent.com/ailab/nlp/zh/download.html),感谢 @Huandeep 整理 https://github.com/iDvel/rime-ice/issues/24
|
||||
#
|
||||
# 只保留三个字及以上的词
|
||||
# 与 base sogou ext 没有重复
|
||||
# 与 base ext 没有重复
|
||||
---
|
||||
name: tencent
|
||||
version: "2023-04-11"
|
||||
version: "2023-04-13"
|
||||
sort: by_weight
|
||||
columns:
|
||||
- text
|
||||
@ -39380,7 +39380,6 @@ columns:
|
||||
不得举办 100
|
||||
不得买 100
|
||||
不得买卖 100
|
||||
不得了了 100
|
||||
不得了啊 100
|
||||
不得了啦 100
|
||||
不得了的事 100
|
||||
@ -88758,9 +88757,6 @@ columns:
|
||||
了不起的挑战 100
|
||||
了不起的自己 100
|
||||
了不起的长城 100
|
||||
了了了 100
|
||||
了了了了 100
|
||||
了了分明 100
|
||||
了元歌 100
|
||||
了凡先生 100
|
||||
了凡尘 100
|
||||
@ -145558,7 +145554,6 @@ columns:
|
||||
你看电视 100
|
||||
你看看别人 100
|
||||
你看看我 100
|
||||
你看着办 100
|
||||
你看见 100
|
||||
你看见了 100
|
||||
你看见我 100
|
||||
@ -261752,7 +261747,6 @@ columns:
|
||||
卡马波夫 100
|
||||
卡骆驰 100
|
||||
卡魔拉 100
|
||||
卡麦隆 100
|
||||
卢一峰 100
|
||||
卢世瑜 100
|
||||
卢东亮 100
|
||||
@ -334568,7 +334562,6 @@ columns:
|
||||
国家的需求 100
|
||||
国家的需要 100
|
||||
国家的骄傲 100
|
||||
国家监委 100
|
||||
国家监察 100
|
||||
国家监察体制改革 100
|
||||
国家监测 100
|
||||
@ -638717,7 +638710,6 @@ columns:
|
||||
最后三分钟 100
|
||||
最后三轮 100
|
||||
最后上场 100
|
||||
最后不了了之 100
|
||||
最后不得已 100
|
||||
最后两位 100
|
||||
最后两分钟 100
|
||||
@ -715501,7 +715493,6 @@ columns:
|
||||
泰勒公式 100
|
||||
泰勒希罗 100
|
||||
泰勒斯 100
|
||||
泰勒斯威夫特 100
|
||||
泰勒约翰逊 100
|
||||
泰华城 100
|
||||
泰华街 100
|
||||
@ -860582,7 +860573,6 @@ columns:
|
||||
算错账 100
|
||||
算长远账 100
|
||||
管一鹤 100
|
||||
管不了了 100
|
||||
管不了那么多了 100
|
||||
管不住嘴巴 100
|
||||
管不住手 100
|
||||
|
@ -14,7 +14,7 @@
|
||||
# 转化应当大写的单词
|
||||
---
|
||||
name: en
|
||||
version: "2023-04-11"
|
||||
version: "2023-04-13"
|
||||
sort: by_weight
|
||||
...
|
||||
# +_+
|
||||
@ -735,7 +735,7 @@ amuse amuse
|
||||
amusement amusement
|
||||
amusing amusing
|
||||
Amy Amy
|
||||
an an
|
||||
# an an
|
||||
ana ana
|
||||
anabolic anabolic
|
||||
anaheim anaheim
|
||||
@ -20955,7 +20955,7 @@ York York
|
||||
yorker yorker
|
||||
Yorkshire Yorkshire
|
||||
Yosemite Yosemite
|
||||
you you
|
||||
# you you
|
||||
young young
|
||||
younger younger
|
||||
youngest youngest
|
||||
|
@ -7,7 +7,7 @@
|
||||
#
|
||||
---
|
||||
name: en_ext
|
||||
version: "2023-04-11"
|
||||
version: "2023-04-13"
|
||||
sort: by_weight
|
||||
...
|
||||
# 一些杂项
|
||||
@ -121,64 +121,6 @@ Chandler Chandler
|
||||
Phoebe Phoebe
|
||||
|
||||
|
||||
# 补充的人名
|
||||
Griffiths Griffiths
|
||||
Chapman Chapman
|
||||
Walsh Walsh
|
||||
Matthews Matthews
|
||||
Patel Patel
|
||||
Willie Willie
|
||||
ChillSeph ChillSeph
|
||||
Ernest Ernest
|
||||
Phillip Phillip
|
||||
Teresa Teresa
|
||||
Doris Doris
|
||||
Evelyn Evelyn
|
||||
Cheryl Cheryl
|
||||
Mildred Mildred
|
||||
Katherine Katherine
|
||||
Judith Judith
|
||||
Janice Janice
|
||||
Theresa Theresa
|
||||
Kimberly Kimberly
|
||||
Denise Denise
|
||||
Irene Irene
|
||||
Shirley Shirley
|
||||
Cynthia Cynthia
|
||||
Brenda Brenda
|
||||
Kathleen Kathleen
|
||||
Jacqueline Jacqueline
|
||||
Wanda Wanda
|
||||
Debra Debra
|
||||
Lois Lois
|
||||
Carolyn Carolyn
|
||||
Tina Tina
|
||||
Phyllis Phyllis
|
||||
Norma Norma
|
||||
Paula Paula
|
||||
Frances Frances
|
||||
Lillian Lillian
|
||||
Olivia Olivia
|
||||
Ava Ava
|
||||
Isabella Isabella
|
||||
Sherlock Sherlock
|
||||
Amelia Amelia
|
||||
Sophia Sophia
|
||||
Abigail Abigail
|
||||
Liam Liam
|
||||
Noah Noah
|
||||
Jay Jay
|
||||
Enya Enya
|
||||
Juno Juno
|
||||
Trump Trump
|
||||
Biden Biden
|
||||
Joseph Joseph
|
||||
Braun Braun
|
||||
Bayes Bayes
|
||||
Saul Saul
|
||||
Wick Wick
|
||||
#///
|
||||
|
||||
# 带权重的系列
|
||||
iPhone iPhone 999
|
||||
iPhone 14 iPhone 4
|
||||
@ -254,6 +196,61 @@ Windows 11 Windows 11
|
||||
|
||||
# 往下开始都是扩展单词
|
||||
# +_+
|
||||
Griffiths Griffiths
|
||||
Chapman Chapman
|
||||
Walsh Walsh
|
||||
Matthews Matthews
|
||||
Patel Patel
|
||||
Willie Willie
|
||||
ChillSeph ChillSeph
|
||||
Ernest Ernest
|
||||
Phillip Phillip
|
||||
Teresa Teresa
|
||||
Doris Doris
|
||||
Evelyn Evelyn
|
||||
Cheryl Cheryl
|
||||
Mildred Mildred
|
||||
Katherine Katherine
|
||||
Judith Judith
|
||||
Janice Janice
|
||||
Theresa Theresa
|
||||
Kimberly Kimberly
|
||||
Denise Denise
|
||||
Irene Irene
|
||||
Shirley Shirley
|
||||
Cynthia Cynthia
|
||||
Brenda Brenda
|
||||
Kathleen Kathleen
|
||||
Jacqueline Jacqueline
|
||||
Wanda Wanda
|
||||
Debra Debra
|
||||
Lois Lois
|
||||
Carolyn Carolyn
|
||||
Tina Tina
|
||||
Phyllis Phyllis
|
||||
Norma Norma
|
||||
Paula Paula
|
||||
Frances Frances
|
||||
Lillian Lillian
|
||||
Olivia Olivia
|
||||
Ava Ava
|
||||
Isabella Isabella
|
||||
Sherlock Sherlock
|
||||
Amelia Amelia
|
||||
Sophia Sophia
|
||||
Abigail Abigail
|
||||
Liam Liam
|
||||
Noah Noah
|
||||
Jay Jay
|
||||
Enya Enya
|
||||
Juno Juno
|
||||
Trump Trump
|
||||
Biden Biden
|
||||
Joseph Joseph
|
||||
Braun Braun
|
||||
Bayes Bayes
|
||||
Saul Saul
|
||||
Wick Wick
|
||||
RPG RPG
|
||||
Role-Playing Game RPG
|
||||
Role-Playing Game RolePlayingGame
|
||||
@ -892,6 +889,7 @@ Windows Phone WindowsPhone
|
||||
Workflow Workflow
|
||||
WorkFlowy WorkFlowy
|
||||
WWDC WWDC
|
||||
Apple Worldwide Developers Conference WWDC
|
||||
Xee Xee
|
||||
Xeon Xeon
|
||||
Xmind Xmind
|
||||
@ -2074,3 +2072,5 @@ Universally Unique Identifier UUID
|
||||
stargazers stargazers
|
||||
fallback fallback
|
||||
Fyne Fyne
|
||||
Claude Claude
|
||||
overdue overdue
|
||||
|
@ -506,6 +506,8 @@ love love 💓 💕 👩❤️👨
|
||||
火上之心 火上之心 ❤️🔥
|
||||
心火 心火 ❤️🔥
|
||||
燃烧的心 燃烧的心 ❤️🔥
|
||||
心在燃烧 心在燃烧 ❤️🔥
|
||||
心在着火 心在着火 ❤️🔥
|
||||
修复受伤的心灵 修复受伤的心灵 ❤️🩹
|
||||
治愈的心 治愈的心 ❤️🩹
|
||||
受伤的心 受伤的心 ❤️🩹
|
||||
@ -2525,6 +2527,7 @@ UFO UFO 🛸
|
||||
点燃 点燃 🔥
|
||||
着火 着火 🔥
|
||||
着火了 着火了 🔥
|
||||
火了 火了 🔥
|
||||
波浪 波浪 🌊
|
||||
浪花 浪花 🌊
|
||||
万圣节 万圣节 🎃
|
||||
@ -3656,6 +3659,9 @@ Wi-Fi Wi-Fi 🛜
|
||||
错 错 ❌ ❎
|
||||
错号 错号 ❌ ❎
|
||||
错误 错误 ❌ ❎
|
||||
叉 叉 ❌ ❎
|
||||
叉叉 叉叉 ❌ ❎
|
||||
画叉 画叉 ❌ ❎
|
||||
卷曲环 卷曲环 ➰
|
||||
双卷曲环 双卷曲环 ➿
|
||||
歌记号 歌记号 〽️
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Emoji 映射表
|
||||
# 根据此文件生成 emoji.txt
|
||||
#
|
||||
# version: "2023-04-11"
|
||||
# version: "2023-04-13"
|
||||
#
|
||||
# 中文映射由 Dvel 纯手工打造 https://github.com/iDvel/rime-ice
|
||||
#
|
||||
@ -181,7 +181,7 @@ S$ 新加坡元 新加坡币
|
||||
💟 心型装饰
|
||||
❣️ 心叹号
|
||||
💔 伤心 心碎 失恋
|
||||
❤️🔥 火上之心 心火 燃烧的心
|
||||
❤️🔥 火上之心 心火 燃烧的心 心在燃烧 心在着火
|
||||
❤️🩹 修复受伤的心灵 治愈的心 受伤 受伤的心 受伤的心灵 心伤
|
||||
# ❤
|
||||
🩷 粉心 粉色心 粉色的心 粉红心
|
||||
@ -1128,7 +1128,7 @@ S$ 新加坡元 新加坡币
|
||||
# ☃
|
||||
⛄ 雪人
|
||||
☄️ 彗星 哈雷 哈雷彗星
|
||||
🔥 火 火焰 燃烧 点燃 着火 着火了
|
||||
🔥 火 火焰 燃烧 点燃 着火 着火了 火了
|
||||
💧 水珠 水滴
|
||||
🌊 波浪 浪花
|
||||
### Activities
|
||||
@ -1640,8 +1640,8 @@ S$ 新加坡元 新加坡币
|
||||
✅ 对 对号 对钩 勾选 正确
|
||||
☑️ 按钮 复选 复选框 复选按钮 打钩 打对钩
|
||||
✔ 对 对号 对钩 勾选 正确
|
||||
❌ 错 错号 错误
|
||||
❎ 错 错号 错误
|
||||
❌ 错 错号 错误 叉 叉叉 画叉
|
||||
❎ 错 错号 错误 叉 叉叉 画叉
|
||||
➰ 卷曲环
|
||||
➿ 双卷曲环
|
||||
〽️ 歌记号
|
||||
|
@ -1,15 +1,5 @@
|
||||
module script
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/commander-cli/cmd v1.5.0
|
||||
github.com/deckarep/golang-set/v2 v2.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
require github.com/deckarep/golang-set/v2 v2.3.0
|
||||
|
@ -1,21 +1,2 @@
|
||||
github.com/commander-cli/cmd v1.5.0 h1:zuMGIdRxQb63R+0Wa9G/g7xtF1fwEERdn+fIIKj5ujI=
|
||||
github.com/commander-cli/cmd v1.5.0/go.mod h1:y9HfHjaDNGRjzpOcMbK43A791NmESwKBkvCSDBCxJ94=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
|
||||
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g=
|
||||
github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||
|
@ -11,49 +11,37 @@ import (
|
||||
func main() {
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
|
||||
// 临时用的
|
||||
// rime.Temp()
|
||||
|
||||
// Emoji 检查和更新
|
||||
rime.CheckEmoji()
|
||||
rime.UpdateEmojiTXT()
|
||||
rime.CheckAndGenerateEmoji()
|
||||
fmt.Println("--------------------------------------------------")
|
||||
|
||||
// 更新搜狗流行词
|
||||
rime.UpdateSogou()
|
||||
fmt.Println("--------------------------------------------------")
|
||||
|
||||
// 为 sogou、ext、tencent 没权重的词条加上权重,有权重的改为下面设置的权重
|
||||
rime.AddWeight(rime.SogouPath, rime.DefaultWeight)
|
||||
// 为 ext、tencent 没权重的词条加上权重,有权重的改为下面设置的权重
|
||||
rime.AddWeight(rime.ExtPath, rime.DefaultWeight)
|
||||
rime.AddWeight(rime.TencentPath, rime.DefaultWeight)
|
||||
fmt.Println("--------------------------------------------------")
|
||||
|
||||
// 通用检查
|
||||
// flag: 1 只有汉字,2 汉字+注音,3 汉字+注音+权重,4 汉字+权重。
|
||||
go rime.Check(rime.HanziPath, 3)
|
||||
go rime.Check(rime.BasePath, 3)
|
||||
go rime.Check(rime.SogouPath, 3)
|
||||
go rime.Check(rime.ExtPath, 4)
|
||||
go rime.Check(rime.TencentPath, 4)
|
||||
// 检查
|
||||
// _type: 1 只有汉字 2 汉字+注音 3 汉字+注音+权重 4 汉字+权重
|
||||
rime.Check(rime.HanziPath, 3)
|
||||
rime.Check(rime.BasePath, 3)
|
||||
rime.Check(rime.ExtPath, 4)
|
||||
rime.Check(rime.TencentPath, 4)
|
||||
fmt.Println("--------------------------------------------------")
|
||||
|
||||
wait()
|
||||
areYouOK()
|
||||
|
||||
// 排序
|
||||
// 排序,顺便去重
|
||||
rime.Sort(rime.HanziPath, 3)
|
||||
rime.Sort(rime.BasePath, 3)
|
||||
rime.Sort(rime.SogouPath, 3) // 对 base 中已经有的,去重
|
||||
rime.Sort(rime.ExtPath, 4) // 对 base、sogou 中已经有的,去重
|
||||
rime.Sort(rime.TencentPath, 4) // 对 base、sogou、ext 中已经有的,去重
|
||||
// rime.SortEnDict(rime.EnPath)
|
||||
rime.Sort(rime.ExtPath, 4)
|
||||
rime.Sort(rime.TencentPath, 4)
|
||||
}
|
||||
|
||||
func wait() {
|
||||
fmt.Println("检查完成后输入 OK 以继续。。。")
|
||||
func areYouOK() {
|
||||
fmt.Println("Are you OK:")
|
||||
var isOK string
|
||||
_, _ = fmt.Scanf("%s", &isOK)
|
||||
if strings.ToLower(isOK) != "ok" {
|
||||
os.Exit(123)
|
||||
}
|
||||
fmt.Println("--------------------------------------------------")
|
||||
}
|
||||
|
@ -3,28 +3,33 @@ package rime
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
var specialWords = mapset.NewSet[string]() // 特殊词汇列表,不进行任何检查
|
||||
var polyphoneWords = mapset.NewSet[string]() // 需要注音的多音字列表
|
||||
var wrongWords = mapset.NewSet[string]() // 异形词、错别字列表
|
||||
var filterWords = mapset.NewSet[string]() // 与异形词列表同时使用,过滤掉,一般是包含异形词但不是异形词的,比如「作爱」是错的,但「叫作爱」是正确的。
|
||||
var hanPinyinMap = make(map[string][]string) // 汉字拼音映射map,用于检查注音是否正确
|
||||
var filterPinyins = mapset.NewSet[string]() // 与汉字拼音映射map同时使用,过滤掉,比如「深厉浅揭qi」只在这个词中念qi,并不是错误。
|
||||
var (
|
||||
specialWords = mapset.NewSet[string]() // 特殊词汇列表,不进行任何检查
|
||||
|
||||
// 初始化特殊词汇列表、多音字列表、异形词列表、汉字拼音映射
|
||||
polyphoneWords = mapset.NewSet[string]() // 需要注音的字词
|
||||
|
||||
wrongWords = mapset.NewSet[string]() // 异形词、错别字
|
||||
wrongWordsFilter = mapset.NewSet[string]() // 过滤一部分,包含错别字但不是错别字,如「作爱」是错的,但「叫作爱」是对的
|
||||
|
||||
hanPinyin = make(map[string][]string) // 汉字拼音映射,用于检查注音是否正确
|
||||
hanPinyinFilter = mapset.NewSet[string]() // 过滤一部分,比如「深厉浅揭qi」只在这个词中念qi,并不是错误。
|
||||
)
|
||||
|
||||
// 初始化特殊词汇列表、需要注音列表、错别字列表、拼音列表
|
||||
func init() {
|
||||
// 特殊词汇列表 specialWords,不进行任何检查
|
||||
// 特殊词汇列表,不进行任何检查
|
||||
specialWords.Add("狄尔斯–阿尔德反应")
|
||||
specialWords.Add("特里斯坦–达库尼亚")
|
||||
specialWords.Add("特里斯坦–达库尼亚群岛")
|
||||
@ -37,13 +42,13 @@ func init() {
|
||||
specialWords.Add("赛博朋克:命运之轮")
|
||||
specialWords.Add("哈勃–勒梅特定律")
|
||||
|
||||
// 需要注音的多音字列表 polyphoneWords
|
||||
file, err := os.Open("rime/多音字.txt")
|
||||
// 需要注音的列表
|
||||
file1, err := os.Open(需要注音TXT)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
sc := bufio.NewScanner(file)
|
||||
defer file1.Close()
|
||||
sc := bufio.NewScanner(file1)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "#") {
|
||||
@ -52,38 +57,36 @@ func init() {
|
||||
polyphoneWords.Add(line)
|
||||
}
|
||||
|
||||
// 异形词的两个列表 wrongWords filterWords
|
||||
file, err = os.Open("rime/异形词.txt")
|
||||
// 错别字的两个列表: wrongWords wrongWordsFilter
|
||||
file2, err := os.Open(错别字TXT)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
sc = bufio.NewScanner(file)
|
||||
defer file2.Close()
|
||||
sc = bufio.NewScanner(file2)
|
||||
isMark := false
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
|
||||
if strings.Contains(line, "# -_-") {
|
||||
if strings.HasPrefix(line, "# -_-") {
|
||||
isMark = true
|
||||
continue
|
||||
}
|
||||
|
||||
if !isMark {
|
||||
wrongWords.Add(line)
|
||||
} else {
|
||||
filterWords.Add(line)
|
||||
wrongWordsFilter.Add(line)
|
||||
}
|
||||
}
|
||||
|
||||
// 汉字拼音映射的 map
|
||||
// 字表的所有读音: hanPinyinMap
|
||||
file, err = os.Open(HanziPath)
|
||||
// 汉字拼音映射 hanPinyin hanPinyinFilter
|
||||
// 将所有读音读入 hanPinyin
|
||||
file3, err := os.Open(HanziPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
defer file3.Close()
|
||||
isMark = false
|
||||
sc = bufio.NewScanner(file)
|
||||
sc = bufio.NewScanner(file3)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
@ -94,19 +97,19 @@ func init() {
|
||||
}
|
||||
parts := strings.Split(line, "\t")
|
||||
text, code := parts[0], parts[1]
|
||||
hanPinyinMap[text] = append(hanPinyinMap[text], code)
|
||||
hanPinyin[text] = append(hanPinyin[text], code)
|
||||
}
|
||||
// 给 hanPinyinMap 补充不在字表的读音,和过滤列表 filterPinyins
|
||||
file, err = os.Open("rime/汉字拼音映射.txt")
|
||||
// 给 hanPinyin 补充不再字表的读音,和过滤列表 hanPinyinFilter
|
||||
file4, err := os.Open(汉字拼音映射TXT)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
sc = bufio.NewScanner(file)
|
||||
defer file4.Close()
|
||||
sc = bufio.NewScanner(file4)
|
||||
isMark = false
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "#") && !strings.Contains(line, "# -_-") || line == "" {
|
||||
if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "# -_-") || line == "" {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "# -_-") {
|
||||
@ -117,22 +120,24 @@ func init() {
|
||||
parts := strings.Split(line, " ")
|
||||
key := parts[0]
|
||||
values := parts[1:]
|
||||
hanPinyinMap[key] = append(hanPinyinMap[key], values...)
|
||||
hanPinyin[key] = append(hanPinyin[key], values...)
|
||||
} else {
|
||||
filterPinyins.Add(line)
|
||||
hanPinyinFilter.Add(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check 对传入的词库文件进行检查
|
||||
func Check(dictPath string, flag int) {
|
||||
// dictPath: 词库文件路径
|
||||
// _type: 词库类型 1 只有汉字 2 汉字+注音 3 汉字+注音+权重 4 汉字+权重
|
||||
func Check(dictPath string, _type int) {
|
||||
// 控制台输出
|
||||
defer printlnTimeCost("检查 "+path.Base(dictPath), time.Now())
|
||||
|
||||
// 打开文件
|
||||
file, err := os.Open(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
@ -140,156 +145,166 @@ func Check(dictPath string, flag int) {
|
||||
lineNumber := 0
|
||||
isMark := false
|
||||
sc := bufio.NewScanner(file)
|
||||
var wg sync.WaitGroup
|
||||
for sc.Scan() {
|
||||
lineNumber++
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if line == mark {
|
||||
if strings.HasPrefix(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go checkLine(dictPath, _type, line, lineNumber, &wg)
|
||||
}
|
||||
|
||||
// 忽略注释,base 里有很多被注释了的词汇,暂时没有删除
|
||||
if strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// 注释以"#"开头,但不是以"# "开头(没有空格)(强迫症晚期)
|
||||
if strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "# ") {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// 检查一行
|
||||
func checkLine(dictPath string, _type int, line string, lineNumber int, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
// 忽略注释,base 中有很多被注视了词汇,暂时没有删除
|
||||
if strings.HasPrefix(line, "#") {
|
||||
// 注释以 '#' 开头,但不是以 '# '开头(强迫症晚期)
|
||||
if !strings.HasPrefix(line, "# ") {
|
||||
fmt.Println("has # but not #␣", line)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 是否有空行
|
||||
if strings.TrimSpace(line) == "" {
|
||||
fmt.Println("空行,行号:", lineNumber)
|
||||
// 有空行
|
||||
if strings.TrimSpace(line) == "" {
|
||||
fmt.Println("empty line", line)
|
||||
}
|
||||
|
||||
// 开头结尾有空格
|
||||
if strings.HasPrefix(line, " ") || strings.HasSuffix(line, " ") {
|
||||
fmt.Println()
|
||||
}
|
||||
// +---------------------------------------------------------------
|
||||
// | 开始检查分割后的内容,分割为: 词汇text 编码code 权重weight
|
||||
// +---------------------------------------------------------------
|
||||
parts := strings.Split(line, "\t")
|
||||
var text, code, weight string
|
||||
switch {
|
||||
case _type == 1 && len(parts) == 1: // 一列,【汉字】
|
||||
text = parts[0]
|
||||
case _type == 2 && len(parts) == 2: // 两列,【汉字+注音】
|
||||
text, code = parts[0], parts[1]
|
||||
case _type == 3 && len(parts) == 3: // 散列,【汉字+注音+权重】
|
||||
text, code, weight = parts[0], parts[1], parts[2]
|
||||
case _type == 4 && len(parts) == 2: // 两列,【汉字+权重】
|
||||
text, weight = parts[0], parts[1]
|
||||
default:
|
||||
log.Fatalln("❌ 分割错误:", line)
|
||||
}
|
||||
|
||||
// weight 应该是纯数字
|
||||
if weight != "" {
|
||||
_, err := strconv.Atoi(weight)
|
||||
if err != nil {
|
||||
fmt.Println("❌ weight 非数字:", line)
|
||||
}
|
||||
}
|
||||
|
||||
// 开头结尾是否有空字符
|
||||
if line != strings.TrimSpace(line) {
|
||||
fmt.Printf("开头或结尾有空格:%q\n", line)
|
||||
// text 和 weight 不应该含有空格
|
||||
if strings.Contains(text, " ") || strings.Contains(weight, " ") {
|
||||
fmt.Println("❌ text 和 weight 含有空格:", line)
|
||||
}
|
||||
|
||||
// code 前后不应该有空格
|
||||
if strings.HasPrefix(code, " ") || strings.HasSuffix(code, " ") {
|
||||
fmt.Println("❌ code 前后有空格:", line)
|
||||
}
|
||||
|
||||
// code 不应该有非小写字母
|
||||
for _, r := range code {
|
||||
if string(r) != " " && !unicode.IsLower(r) {
|
||||
fmt.Println("❌ code 含有非小写字母:", line)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// +---------------------------------------------------------------
|
||||
// | 通用检查:分割为:词汇text, 编码code, 权重weight
|
||||
// +---------------------------------------------------------------
|
||||
parts := strings.Split(line, "\t")
|
||||
var text, code, weight string
|
||||
if flag == 1 && len(parts) == 1 { // 一列,【汉字】:外部词库
|
||||
text = parts[0]
|
||||
} else if flag == 2 && len(parts) == 2 { // 两列,【汉字+注音】:外部词库
|
||||
text, code = parts[0], parts[1]
|
||||
} else if flag == 3 && len(parts) == 3 { // 三列,【汉字+注音+权重】:字表 base av sogou
|
||||
text, code, weight = parts[0], parts[1], parts[2]
|
||||
} else if flag == 4 && len(parts) == 2 { // 两列,【汉字+权重】:ext tencent
|
||||
text, weight = parts[0], parts[1]
|
||||
} else {
|
||||
log.Fatal("分割错误:", line)
|
||||
// 过滤特殊词条
|
||||
if specialWords.Contains(text) {
|
||||
return
|
||||
}
|
||||
|
||||
// text 不应该有非汉字内容,除了间隔号 ·
|
||||
for _, c := range text {
|
||||
if string(c) != "·" && !unicode.Is(unicode.Han, c) {
|
||||
fmt.Println("❌ text 含有非汉字内容:", line)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 检查:weight 应该是纯数字
|
||||
if weight != "" {
|
||||
_, err := strconv.Atoi(weight)
|
||||
if err != nil {
|
||||
fmt.Println("weight 非数字:", line)
|
||||
// 除了字表,其他词库不应该含有单个的汉字
|
||||
if dictPath != HanziPath && utf8.RuneCountInString(text) == 1 {
|
||||
fmt.Println("❌ 意外的单个汉字:", line)
|
||||
}
|
||||
|
||||
// 除了 base,其他词库不应该含有两个字的词汇
|
||||
if dictPath != BasePath && utf8.RuneCountInString(text) == 2 {
|
||||
fmt.Println("❌ 意外的两字词:", line)
|
||||
}
|
||||
|
||||
// 汉字个数应该和拼音个数相等
|
||||
if code != "" {
|
||||
codeCount := len(strings.Split(code, " "))
|
||||
textCount := utf8.RuneCountInString(text)
|
||||
if strings.Contains(text, "·") {
|
||||
textCount -= strings.Count(text, "·")
|
||||
}
|
||||
if strings.HasPrefix(text, "# ") {
|
||||
textCount -= 2
|
||||
}
|
||||
if textCount != codeCount {
|
||||
fmt.Println("❌ 汉字个数 != 拼音个数:", line)
|
||||
}
|
||||
}
|
||||
|
||||
// +---------------------------------------------------------------
|
||||
// | 其他检查
|
||||
// +---------------------------------------------------------------
|
||||
|
||||
// 需要注音但没有注音的字
|
||||
if dictPath == ExtPath || dictPath == TencentPath {
|
||||
for _, word := range polyphoneWords.ToSlice() {
|
||||
if strings.Contains(text, word) {
|
||||
fmt.Println("❌ 需要注音:", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤特殊词条
|
||||
if specialWords.Contains(text) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查:text 和 weight 不应该含有空格
|
||||
if strings.Contains(text, " ") || strings.Contains(weight, " ") {
|
||||
fmt.Println("text 和 weight 不应该含有空格:", line)
|
||||
}
|
||||
|
||||
// 检查:code 前后不应该含有空格
|
||||
if strings.HasPrefix(code, " ") || strings.HasSuffix(code, " ") {
|
||||
fmt.Println("code 前后不应该含有空格:", line)
|
||||
}
|
||||
|
||||
// 检查:code 是否含有非字母,或没有小写
|
||||
for _, r := range code {
|
||||
if string(r) != " " && !unicode.IsLower(r) {
|
||||
fmt.Println("编码含有非字母或大写字母:", line)
|
||||
break
|
||||
// 检查拼写错误,如「赞zan」写成了zna;顺便检查是否存在字表中没有注音的字
|
||||
if dictPath != HanziPath && (_type == 2 || _type == 3) && !hanPinyinFilter.Contains(text) {
|
||||
// 把汉字和拼音弄成一一对应关系,「拼音:pin yin」→「拼:pin」「音:yin」
|
||||
textWithoutDian := strings.ReplaceAll(text, "·", "") // 去掉间隔号
|
||||
pinyins := strings.Split(code, " ")
|
||||
i := 0
|
||||
for _, zi := range textWithoutDian {
|
||||
if !contains(hanPinyin[string(zi)], pinyins[i]) {
|
||||
fmt.Printf("注音错误 or 字表未包含的汉字及注音: %s - %s.+%s\n", line, string(zi), pinyins[i])
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// 检查:text 是否含有非汉字内容
|
||||
for _, c := range text {
|
||||
if string(c) != "·" && !unicode.Is(unicode.Han, c) {
|
||||
fmt.Println("含有非汉字内容:", line, c)
|
||||
break
|
||||
// 错别字检查,最耗时的检查
|
||||
if dictPath != HanziPath && !wrongWordsFilter.Contains(text) {
|
||||
wrongWords.Each(func(wrongWord string) bool {
|
||||
if strings.Contains(text, wrongWord) {
|
||||
fmt.Printf("❌ 错别字: %s - %s\n", text, wrongWord)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 除了字表,其他词库不应该含有单个的汉字
|
||||
if dictPath != HanziPath && utf8.RuneCountInString(text) == 1 {
|
||||
fmt.Println("意外的单个汉字:", line)
|
||||
}
|
||||
|
||||
// 除了 base ,其他词库不应该含有两个字的词汇
|
||||
if dictPath != BasePath && utf8.RuneCountInString(text) == 2 {
|
||||
fmt.Println("意外的两字词:", line)
|
||||
}
|
||||
|
||||
// 汉字个数应该与拼音个数相等
|
||||
if code != "" {
|
||||
codeCount := len(strings.Split(code, " "))
|
||||
textCount := utf8.RuneCountInString(text)
|
||||
if strings.Contains(text, "·") {
|
||||
textCount -= strings.Count(text, "·")
|
||||
}
|
||||
if strings.HasPrefix(text, "# ") {
|
||||
textCount -= 2
|
||||
}
|
||||
if textCount != codeCount {
|
||||
fmt.Println("汉字个数和拼音个数不相等:", text, code)
|
||||
}
|
||||
}
|
||||
|
||||
// +---------------------------------------------------------------
|
||||
// | 比较耗时的检查
|
||||
// +---------------------------------------------------------------
|
||||
// 检查拼写错误,如「赞zan」写成了zna;或者存在字表中没有注音的字
|
||||
go func() {
|
||||
if dictPath != HanziPath && (flag == 2 || flag == 3) && !filterPinyins.Contains(text) {
|
||||
// 把汉字和拼音弄成一一对应关系,「拼音:pin yin」→「拼:pin」「音:yin」
|
||||
textWithoutDian := strings.ReplaceAll(text, "·", "") // 去掉间隔号
|
||||
pinyins := strings.Split(code, " ")
|
||||
i := 0
|
||||
for _, zi := range textWithoutDian {
|
||||
if !contains(hanPinyinMap[string(zi)], pinyins[i]) {
|
||||
fmt.Printf("注音错误 or 字表未包含的汉字及注音: %s - %s.+%s\n", line, string(zi), pinyins[i])
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// 多音字注音问题检查
|
||||
go func() {
|
||||
if dictPath == ExtPath || dictPath == TencentPath {
|
||||
for _, word := range polyphoneWords.ToSlice() {
|
||||
if strings.Contains(text, word) {
|
||||
fmt.Printf("多音字注音问题:%q\n", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// 异形词检查
|
||||
go func() {
|
||||
if dictPath != HanziPath && !filterWords.Contains(text) {
|
||||
for _, wrongWord := range wrongWords.ToSlice() {
|
||||
if strings.Contains(text, wrongWord) {
|
||||
fmt.Printf("异形词汇: %s - %s\n", wrongWord, text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
return false
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -3,39 +3,36 @@ package rime
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
var emojiTXT = "/Users/dvel/Library/Rime/opencc/emoji.txt"
|
||||
var mappingTXT = "/Users/dvel/Library/Rime/others/emoji-map.txt"
|
||||
// CheckAndGenerateEmoji
|
||||
// 检查 emoji-map.txt 是否合法,检查中文映射是否存在于 base 词库中
|
||||
// 生成 Rime 格式的 emoji.txt
|
||||
func CheckAndGenerateEmoji() {
|
||||
// 控制台输出
|
||||
defer printlnTimeCost("检查、更新 Emoji", time.Now())
|
||||
|
||||
type OrderedMap struct {
|
||||
keys []string
|
||||
m map[string][]string
|
||||
checkEmoji()
|
||||
generateEmoji()
|
||||
}
|
||||
|
||||
// CheckEmoji 检查 Emoji
|
||||
// 检查 emoji-map.txt 格式书写问题
|
||||
// 检查所有词条是否与 base 词库存在差集
|
||||
func CheckEmoji() {
|
||||
// 控制台输出
|
||||
defer printlnTimeCost("检查 Emoji 差集", time.Now())
|
||||
|
||||
// 检查 emoji-map.txt 是否合法,检查中文映射是否存在于 base 词库中
|
||||
func checkEmoji() {
|
||||
// 打开文件
|
||||
file, err := os.Open(EmojiPath)
|
||||
file, err := os.Open(EmojiMapPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 将 Emoji 加入 set,为检测差集做准备
|
||||
// 将 Emoji 加入一个 set,为检测差集做准备
|
||||
emojiSet := mapset.NewSet[string]()
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
@ -48,91 +45,101 @@ func CheckEmoji() {
|
||||
if strings.Contains(line, "#") {
|
||||
continue
|
||||
}
|
||||
// 检查是否包含 Tab
|
||||
// 检查:是否包含 Tab
|
||||
if strings.Contains(line, "\t") {
|
||||
fmt.Println("❌ 此行包含 Tab:", line)
|
||||
fmt.Println("❌ contains Tab:", line)
|
||||
continue
|
||||
}
|
||||
// 开头结尾无效的空格
|
||||
// 检查:开头结尾无效的空格
|
||||
if strings.HasPrefix(line, " ") || strings.HasSuffix(line, " ") {
|
||||
fmt.Println("❌ unexpected space:", line)
|
||||
fmt.Println("❌ unexpected space:", line)
|
||||
continue
|
||||
}
|
||||
// 开始分割
|
||||
parts := strings.Split(line, " ")
|
||||
if len(parts) < 2 {
|
||||
fmt.Println("❌ invalid line:", line)
|
||||
fmt.Println("❌ invalid line:", line)
|
||||
continue
|
||||
}
|
||||
// 加入 emojiSet,顺便用一个 tempSet 查重
|
||||
tempSet := mapset.NewSet[string]()
|
||||
for _, word := range parts[1:] {
|
||||
emojiSet.Add(word)
|
||||
if tempSet.Contains(word) {
|
||||
fmt.Println("❌ 此行有重复映射:", line)
|
||||
for _, text := range parts[1:] {
|
||||
emojiSet.Add(text)
|
||||
if tempSet.Contains(text) {
|
||||
fmt.Println("❌ duplicate mapping:", text)
|
||||
} else {
|
||||
tempSet.Add(word)
|
||||
tempSet.Add(text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 emoji 中的词条是否与 base+sogou+ext 词库存在差集
|
||||
for _, word := range emojiSet.Difference(BaseSet).ToSlice() {
|
||||
// 去除英文字母
|
||||
if match, _ := regexp.MatchString(`[A-Za-z]+`, word); match {
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// 检查: emoji-map.txt 中的映射是否存在于 base 词库中,有差集即不存在
|
||||
for _, text := range emojiSet.Difference(BaseSet).ToSlice() {
|
||||
// 不检查英文
|
||||
if match, _ := regexp.MatchString(`[a-zA-Z]`, text); match {
|
||||
continue
|
||||
}
|
||||
// 去除一个字的
|
||||
if utf8.RuneCountInString(word) == 1 {
|
||||
// 不检查 1 个字的
|
||||
if utf8.RuneCountInString(text) == 1 {
|
||||
continue
|
||||
}
|
||||
fmt.Println("❌ Emoji 差集:", word)
|
||||
fmt.Println("❌ Emoji 与 base 的差集:", text)
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateEmojiTXT 从 emoji-map.txt 生成或更新 emoji.txt
|
||||
func UpdateEmojiTXT() {
|
||||
// 控制台输出
|
||||
defer printlnTimeCost("更新 emoji.txt", time.Now())
|
||||
|
||||
// 读取 emoji-map.txt
|
||||
mappingFile, err := os.Open(mappingTXT)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer mappingFile.Close()
|
||||
|
||||
om := new(OrderedMap)
|
||||
om.keys = make([]string, 0)
|
||||
om.m = make(map[string][]string)
|
||||
|
||||
sc := bufio.NewScanner(mappingFile)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "#") && !strings.Contains(line, "井号") { // #️⃣被判断为以 # 开头了。。。
|
||||
continue
|
||||
}
|
||||
arr := strings.Split(line, " ")
|
||||
for _, word := range arr[1:] {
|
||||
if !contains(om.keys, word) {
|
||||
om.keys = append(om.keys, word)
|
||||
}
|
||||
om.m[word] = append(om.m[word], arr[0])
|
||||
}
|
||||
}
|
||||
|
||||
// 写入 emoji.txt
|
||||
emojiFile, err := os.OpenFile(emojiTXT, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
// 从 emoji-map.txt 生成或更新 emoji.txt
|
||||
func generateEmoji() {
|
||||
// 打开文件
|
||||
file, err := os.Open(EmojiMapPath)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer emojiFile.Close()
|
||||
defer file.Close()
|
||||
|
||||
for _, key := range om.keys {
|
||||
line := key + "\t" + key + " " + strings.Join(om.m[key], " ") + "\n"
|
||||
_, err := emojiFile.WriteString(line)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
// 模拟有序字典
|
||||
OmKeys := make([]string, 0)
|
||||
OmMap := make(map[string][]string)
|
||||
|
||||
// 将映射读取到字典里
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "#") && !strings.Contains(line, "井号") { // 井号的 Emoji 被判断为以 # 开头了。。。
|
||||
continue
|
||||
}
|
||||
parts := strings.Split(line, " ")
|
||||
for _, text := range parts[1:] {
|
||||
if !contains(OmKeys, text) {
|
||||
OmKeys = append(OmKeys, text)
|
||||
}
|
||||
OmMap[text] = append(OmMap[text], parts[0])
|
||||
}
|
||||
}
|
||||
|
||||
if err := emojiFile.Sync(); err != nil {
|
||||
log.Fatal(err)
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// 写入 emoji.txt
|
||||
file, err = os.OpenFile(EmojiPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
for _, key := range OmKeys {
|
||||
line := key + "\t" + key + " " + strings.Join(OmMap[key], " ") + "\n"
|
||||
_, err := file.WriteString(line)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := file.Sync(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
@ -1,139 +0,0 @@
|
||||
package rime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
// SortEnDict 排序 en.dict.yaml 词库
|
||||
func SortEnDict(dictPath string) {
|
||||
file, err := os.OpenFile(dictPath, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 前缀内容和词库切片,前者原封不动写入,后者排序后写入
|
||||
prefixContents := make([]string, 0) // 前置内容切片
|
||||
contents := make([][]string, 0) // 词库切片
|
||||
|
||||
// 读取
|
||||
isMark := false
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
prefixContents = append(prefixContents, line)
|
||||
if line == mark {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
parts := strings.Split(line, "\t")
|
||||
contents = append(contents, []string{parts[0], parts[1]})
|
||||
}
|
||||
|
||||
// 排序
|
||||
sort.Slice(contents, func(i, j int) bool {
|
||||
if contents[i][1] != contents[j][1] {
|
||||
return strings.ToLower(contents[i][1]) < strings.ToLower(contents[j][1])
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// 准备写入
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// 写入前缀
|
||||
for _, line := range prefixContents {
|
||||
_, err := file.WriteString(line + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 写入词库
|
||||
for _, content := range contents {
|
||||
_, err := file.WriteString(strings.Join(content, "\t") + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 将 en 词库加入 set,同时包含被注释的词汇,并且都转为小写
|
||||
func readEnToSet(dictPath string) mapset.Set[string] {
|
||||
set := mapset.NewSet[string]()
|
||||
|
||||
file, err := os.Open(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
sc := bufio.NewScanner(file)
|
||||
isMark := false
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if strings.Contains(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
word := strings.Split(line, "\t")[0]
|
||||
word = strings.ToLower(word)
|
||||
if strings.HasPrefix(word, "# ") {
|
||||
word = strings.TrimLeft(word, "# ")
|
||||
}
|
||||
set.Add(word)
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
// 把每行只有一个单词的 txt 文本转换为 Rime 格式的词库
|
||||
func enTxtToRimeDict(txtPath string) {
|
||||
txtFile, err := os.Open(txtPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer txtFile.Close()
|
||||
|
||||
outFile, err := os.OpenFile("rime/1.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
sc := bufio.NewScanner(txtFile)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
_, err := outFile.WriteString(line + "\t" + line + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = outFile.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
package rime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// 临时用的或一次性的方法集
|
||||
|
||||
func Temp() {
|
||||
defer os.Exit(1)
|
||||
}
|
||||
|
||||
func dictsDifference(dict1, dict2 string) {
|
||||
file1Set := readToSet(dict1)
|
||||
file2Set := readToSet(dict2)
|
||||
set := file1Set.Difference(file2Set)
|
||||
fmt.Println(set.ToSlice())
|
||||
fmt.Println(set.Cardinality())
|
||||
}
|
||||
|
||||
func dictsIntersect(dict1, dict2 string) {
|
||||
file1Set := readToSet(dict1)
|
||||
file2Set := readToSet(dict2)
|
||||
set := file1Set.Intersect(file2Set)
|
||||
fmt.Println(set.ToSlice())
|
||||
fmt.Println(set.Cardinality())
|
||||
}
|
||||
|
||||
func enDictsIntersect(dict1, dict2 string) {
|
||||
file1Set := readEnToSet(dict1)
|
||||
file2Set := readEnToSet(dict2)
|
||||
set := file1Set.Difference(file2Set)
|
||||
// fmt.Println(set.ToSlice())
|
||||
fmt.Println(set.Cardinality())
|
||||
file, err := os.OpenFile("rime/1.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
for _, word := range set.ToSlice() {
|
||||
_, err := file.WriteString(word + "\t" + word + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理一个 Rime 词库,去除掉它两个字及以下的词汇
|
||||
func processNewDict(dictPath string) {
|
||||
file, _ := os.Open(dictPath)
|
||||
defer file.Close()
|
||||
|
||||
outFile, _ := os.OpenFile("/Users/dvel/Downloads/1.dict.yaml", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
defer outFile.Close()
|
||||
|
||||
sc := bufio.NewScanner(file)
|
||||
isMark := false
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if line == "..." {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
text := strings.Split(line, "\t")[0]
|
||||
if utf8.RuneCountInString(text) <= 2 {
|
||||
continue
|
||||
}
|
||||
outFile.WriteString(line + "\n")
|
||||
}
|
||||
outFile.Sync()
|
||||
}
|
||||
|
||||
func get字表汉字拼音映射() {
|
||||
file, err := os.Open(HanziPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
HanPinYinMap := make(map[string][]string)
|
||||
keys := make([]string, 0) // ordered map
|
||||
isMark := false
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if strings.Contains(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
parts := strings.Split(line, "\t")
|
||||
text, code := parts[0], parts[1]
|
||||
if !contains(keys, text) {
|
||||
keys = append(keys, text)
|
||||
}
|
||||
HanPinYinMap[text] = append(HanPinYinMap[text], code)
|
||||
}
|
||||
|
||||
tempTXT, err := os.OpenFile("rime/temp.txt", os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer tempTXT.Close()
|
||||
|
||||
for _, key := range keys {
|
||||
s := key + " " + strings.Join(HanPinYinMap[key], " ") + "\n"
|
||||
_, err := tempTXT.WriteString(s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
err = tempTXT.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
@ -2,61 +2,64 @@ package rime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"log"
|
||||
"os"
|
||||
"os/user"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
// 一个词条的组成部分
|
||||
// 一个词的组成部分
|
||||
type lemma struct {
|
||||
text string // 汉字
|
||||
code string // 编码
|
||||
weight int // 权重
|
||||
}
|
||||
|
||||
const (
|
||||
mark = "# +_+" // 词库中的标记符号,表示从开始检查或排序
|
||||
HanziPath = "/Users/dvel/Library/Rime/cn_dicts/8105.dict.yaml"
|
||||
BasePath = "/Users/dvel/Library/Rime/cn_dicts/base.dict.yaml"
|
||||
SogouPath = "/Users/dvel/Library/Rime/cn_dicts/sogou.dict.yaml"
|
||||
ExtPath = "/Users/dvel/Library/Rime/cn_dicts/ext.dict.yaml"
|
||||
TencentPath = "/Users/dvel/Library/Rime/cn_dicts/tencent.dict.yaml"
|
||||
EmojiPath = "/Users/dvel/Library/Rime/others/emoji-map.txt"
|
||||
EnPath = "/Users/dvel/Library/Rime/en_dicts/en.dict.yaml"
|
||||
|
||||
DefaultWeight = 100 // sogou、ext、tencet 词库中默认的权重数值
|
||||
)
|
||||
|
||||
var (
|
||||
BaseSet mapset.Set[string]
|
||||
SogouSet mapset.Set[string]
|
||||
ExtSet mapset.Set[string]
|
||||
TencentSet mapset.Set[string]
|
||||
mark = "# +_+" // 词库中的标记符号,表示从这行开始进行检查或排序
|
||||
DefaultWeight = 100 // ext、tencent 词库中默认的权重
|
||||
RimeDir = getRimeDir() // Rime 配置目录
|
||||
|
||||
EmojiMapPath = filepath.Join(RimeDir, "others/emoji-map.txt")
|
||||
EmojiPath = filepath.Join(RimeDir, "opencc/emoji.txt")
|
||||
|
||||
HanziPath = filepath.Join(RimeDir, "cn_dicts/8105.dict.yaml")
|
||||
BasePath = filepath.Join(RimeDir, "cn_dicts/base.dict.yaml")
|
||||
ExtPath = filepath.Join(RimeDir, "cn_dicts/ext.dict.yaml")
|
||||
TencentPath = filepath.Join(RimeDir, "cn_dicts/tencent.dict.yaml")
|
||||
|
||||
HanziSet = readToSet(HanziPath)
|
||||
BaseSet = readToSet(BasePath)
|
||||
ExtSet = readToSet(ExtPath)
|
||||
TencentSet = readToSet(TencentPath)
|
||||
|
||||
需要注音TXT = filepath.Join(RimeDir, "others/script/rime/需要注音.txt")
|
||||
错别字TXT = filepath.Join(RimeDir, "others/script/rime/错别字.txt")
|
||||
汉字拼音映射TXT = filepath.Join(RimeDir, "others/script/rime/汉字拼音映射.txt")
|
||||
)
|
||||
|
||||
func init() {
|
||||
BaseSet = readToSet(BasePath)
|
||||
SogouSet = readToSet(SogouPath)
|
||||
ExtSet = readToSet(ExtPath)
|
||||
TencentSet = readToSet(TencentPath)
|
||||
// 获取 macOS Rime 配置目录
|
||||
func getRimeDir() string {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
return filepath.Join(u.HomeDir, "Library/Rime")
|
||||
}
|
||||
|
||||
// readToSet 读取词库文件为 set
|
||||
// 将所有词库读入 set,供检查或排序使用
|
||||
func readToSet(dictPath string) mapset.Set[string] {
|
||||
set := mapset.NewSet[string]()
|
||||
|
||||
file, err := os.Open(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(set)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
@ -65,7 +68,7 @@ func readToSet(dictPath string) mapset.Set[string] {
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if strings.Contains(line, mark) {
|
||||
if strings.HasPrefix(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
@ -77,17 +80,19 @@ func readToSet(dictPath string) mapset.Set[string] {
|
||||
return set
|
||||
}
|
||||
|
||||
// printlnTimeCost 打印耗时时间
|
||||
// 打印耗时时间
|
||||
func printlnTimeCost(content string, start time.Time) {
|
||||
fmt.Printf("%s:\t%.2fs\n", content, time.Since(start).Seconds())
|
||||
// fmt.Printf("%s:\t%.2fs\n", content, time.Since(start).Seconds())
|
||||
printfTimeCost(content, start)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
// printfTimeCost 打印耗时时间
|
||||
// 打印耗时时间
|
||||
func printfTimeCost(content string, start time.Time) {
|
||||
fmt.Printf("%s:\t%.2fs", content, time.Since(start).Seconds())
|
||||
}
|
||||
|
||||
// contains slice 是否包含 item
|
||||
// slice 是否包含 item
|
||||
func contains(arr []string, item string) bool {
|
||||
for _, x := range arr {
|
||||
if item == x {
|
||||
@ -97,90 +102,22 @@ func contains(arr []string, item string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// getSha1 获取文件 sha1
|
||||
func getSha1(dictPath string) string {
|
||||
f, err := os.Open(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
sha1Handle := sha1.New()
|
||||
if _, err := io.Copy(sha1Handle, f); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(sha1Handle.Sum(nil))
|
||||
}
|
||||
|
||||
// updateVersion 排序后,如果文件有改动,则修改 version 日期
|
||||
func updateVersion(dictPath string, oldSha1 string) {
|
||||
// 判断文件是否有改变
|
||||
newSha1 := getSha1(dictPath)
|
||||
if newSha1 == oldSha1 {
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
fmt.Println(" ...sorted")
|
||||
|
||||
// 打开文件
|
||||
file, err := os.OpenFile(dictPath, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 修改那一行
|
||||
arr := make([]string, 0)
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "version:") {
|
||||
s := fmt.Sprintf("version: \"%s\"", time.Now().Format("2006-01-02"))
|
||||
arr = append(arr, s)
|
||||
} else {
|
||||
arr = append(arr, line)
|
||||
}
|
||||
}
|
||||
|
||||
// 重新写入
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, line := range arr {
|
||||
_, err := file.WriteString(line + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AddWeight 为 ext、tencent 没权重的词条加上权重,有权重的改为 weight
|
||||
func AddWeight(dictPath string, weight int) {
|
||||
// 控制台输出
|
||||
printlnTimeCost("加权重\t"+path.Base(dictPath), time.Now())
|
||||
|
||||
// 读取文件到 lines 数组
|
||||
// 读取到 lines 数组
|
||||
file, err := os.ReadFile(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
lines := strings.Split(string(file), "\n")
|
||||
|
||||
// 逐行遍历,加上 weight
|
||||
isMark := false
|
||||
for i, line := range lines {
|
||||
if !isMark {
|
||||
if strings.Contains(line, mark) {
|
||||
if strings.HasPrefix(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
@ -199,7 +136,7 @@ func AddWeight(dictPath string, weight int) {
|
||||
}
|
||||
}
|
||||
|
||||
// 重新写入
|
||||
// 写入
|
||||
resultString := strings.Join(lines, "\n")
|
||||
err = os.WriteFile(dictPath, []byte(resultString), 0644)
|
||||
if err != nil {
|
||||
|
@ -1,312 +0,0 @@
|
||||
package rime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/commander-cli/cmd"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
var filterMark = "# *_*" // "# *_*" 和 mark 之间是过滤词列表
|
||||
var filterList = mapset.NewSet[string]() // 过滤词列表,在这个列表里的词汇,不再写入
|
||||
|
||||
// UpdateSogou 更新搜狗流行词
|
||||
func UpdateSogou() {
|
||||
// 控制台输出
|
||||
defer updateVersion(SogouPath, getSha1(SogouPath))
|
||||
defer printfTimeCost("更新搜狗流行词", time.Now())
|
||||
|
||||
makeSogouFilterList() // 0. 准备好过滤词列表
|
||||
downloadSogou() // 1. 下载搜狗流行词加入到文件末尾
|
||||
checkAndWrite() // 2. 过滤、去重、排序
|
||||
PrintNewWords() // 3. 打印新增词汇
|
||||
|
||||
// 弄完了删除临时用的文件,否则 VSCode 全局搜索词汇时会搜索到,影响体验
|
||||
err := os.Remove("./scel2txt/scel/sogou.scel")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.Remove("./scel2txt/out/luna_pinyin.sogou.dict.yaml")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = os.Remove("./scel2txt/out/sogou.txt")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 准备好过滤词列表 filterList
|
||||
func makeSogouFilterList() {
|
||||
file, err := os.Open(SogouPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
sc := bufio.NewScanner(file)
|
||||
isFilterMark := false
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if line == mark {
|
||||
break
|
||||
}
|
||||
if !isFilterMark {
|
||||
if strings.Contains(line, filterMark) {
|
||||
isFilterMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
// 判断一些可能出错的情况
|
||||
if !strings.HasPrefix(line, "# ") {
|
||||
log.Fatal("sogou 过滤列表 无效行:", line)
|
||||
}
|
||||
text := strings.TrimPrefix(line, "# ")
|
||||
if strings.ContainsAny(text, " \t") {
|
||||
log.Fatal("sogou 过滤列表 包含空字符:", line)
|
||||
}
|
||||
// 加入过滤词列表
|
||||
filterList.Add(text)
|
||||
}
|
||||
}
|
||||
|
||||
// downloadSogou 下载搜狗流行词加入到文件末尾,如果是新词且不在过滤列表,打印出来
|
||||
func downloadSogou() {
|
||||
// 下载
|
||||
url := "https://pinyin.sogou.com/d/dict/download_cell.php?id=4&name=%E7%BD%91%E7%BB%9C%E6%B5%81%E8%A1%8C%E6%96%B0%E8%AF%8D%E3%80%90%E5%AE%98%E6%96%B9%E6%8E%A8%E8%8D%90%E3%80%91&f=detail"
|
||||
|
||||
// 创建 scel/ 和 out/ 文件夹
|
||||
scelDir := "./scel2txt/scel/"
|
||||
if _, err := os.Stat(scelDir); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(scelDir, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
outDir := "./scel2txt/out/"
|
||||
if _, err := os.Stat(outDir); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(outDir, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the data
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 创建一个文件用于保存
|
||||
out, err := os.Create(filepath.Join(scelDir, "sogou.scel"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// 然后将响应流和文件流对接起来
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 用 Python 进行转换
|
||||
c := cmd.NewCommand("python3 scel2txt.py", cmd.WithWorkingDir("./scel2txt"))
|
||||
err = c.Execute()
|
||||
if err != nil {
|
||||
fmt.Println(c.Stderr())
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf(c.Stdout())
|
||||
|
||||
// 加入到现有词库的末尾
|
||||
sogouFile, err := os.OpenFile(SogouPath, os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sogouFile.Close()
|
||||
download, err := os.ReadFile(filepath.Join(outDir, "sogou.txt"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = sogouFile.Write(download)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = sogouFile.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// checkAndWrite 过滤、去重、排序
|
||||
func checkAndWrite() {
|
||||
// 打开文件
|
||||
file, err := os.OpenFile(SogouPath, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 前缀内容和词库切片,以 mark 隔开
|
||||
prefixContents := make([]string, 0) // 前置内容切片
|
||||
contents := make([]lemma, 0) // 词库切片
|
||||
|
||||
isMark := false
|
||||
set := mapset.NewSet[string]() // 去重用的 set
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
prefixContents = append(prefixContents, line)
|
||||
if strings.Contains(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
// 分割
|
||||
parts := strings.Split(line, "\t")
|
||||
var text, code, weight string
|
||||
switch len(parts) {
|
||||
case 2:
|
||||
text, code = parts[0], parts[1]
|
||||
case 3:
|
||||
text, code, weight = parts[0], parts[1], parts[2]
|
||||
default:
|
||||
log.Fatal("分割错误:", line)
|
||||
}
|
||||
// 过滤:两个字及以下的
|
||||
if utf8.RuneCountInString(text) <= 2 {
|
||||
continue
|
||||
}
|
||||
// 过滤:从过滤列表过滤掉
|
||||
if filterList.Contains(text) {
|
||||
continue
|
||||
}
|
||||
// 过滤:去重
|
||||
if set.Contains(text) {
|
||||
continue
|
||||
}
|
||||
set.Add(text)
|
||||
// 过滤:base 中已经有的就不要了
|
||||
if BaseSet.Contains(text) {
|
||||
continue
|
||||
}
|
||||
// nue → nve,lue → lve
|
||||
if strings.Contains(code, "nue") {
|
||||
code = strings.ReplaceAll(code, "nue", "nve")
|
||||
}
|
||||
if strings.Contains(code, "lue") {
|
||||
code = strings.ReplaceAll(code, "lue", "lve")
|
||||
}
|
||||
// 加入数组,没权重的默认给 DefaultWeight
|
||||
if weight == "" {
|
||||
contents = append(contents, lemma{text, code, DefaultWeight})
|
||||
} else {
|
||||
weightInt, err := strconv.Atoi(weight)
|
||||
if err != nil {
|
||||
log.Fatal(err, line)
|
||||
}
|
||||
contents = append(contents, lemma{text, code, weightInt})
|
||||
}
|
||||
}
|
||||
|
||||
// 排序
|
||||
sort.Slice(contents, func(i, j int) bool {
|
||||
if contents[i].code != contents[j].code {
|
||||
return contents[i].code < contents[j].code
|
||||
}
|
||||
if contents[i].text != contents[j].text {
|
||||
return contents[i].text < contents[j].text
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// 准备写入
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 写入前缀
|
||||
for _, content := range prefixContents {
|
||||
_, err := file.WriteString(content + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 写入词库
|
||||
for _, content := range contents {
|
||||
_, err := file.WriteString(content.text + "\t" + content.code + "\t" + strconv.Itoa(content.weight) + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// PrintNewWords 打印新增词汇
|
||||
func PrintNewWords() {
|
||||
// 对比 sogou 的新旧 set,找出新词汇
|
||||
newSet := readToSet(SogouPath)
|
||||
newWords := newSet.Difference(SogouSet)
|
||||
if newWords.Cardinality() == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("新增词汇:")
|
||||
|
||||
// 打印无注音的
|
||||
// for _, word := range newWords.ToSlice() {
|
||||
// fmt.Println(word)
|
||||
// }
|
||||
|
||||
// 把注音也打出来,方便直接校对
|
||||
file, err := os.Open(SogouPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
isMark := false
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if !isMark {
|
||||
if strings.Contains(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
text := strings.Split(line, "\t")[0]
|
||||
if newWords.Contains(text) {
|
||||
fmt.Println(line)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("count: ", newWords.Cardinality())
|
||||
|
||||
// 更新全局的 set,方便后续的检查
|
||||
SogouSet = newSet
|
||||
}
|
@ -2,7 +2,11 @@ package rime
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
@ -10,13 +14,9 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mapset "github.com/deckarep/golang-set/v2"
|
||||
)
|
||||
|
||||
// Sort 词库排序,顺便去重
|
||||
// flag: 1 只有汉字,2 汉字+注音,3 汉字+注音+权重,4 汉字+权重。
|
||||
func Sort(dictPath string, flag int) {
|
||||
func Sort(dictPath string, _type int) {
|
||||
// 控制台输出
|
||||
defer updateVersion(dictPath, getSha1(dictPath))
|
||||
defer printfTimeCost("排序 "+path.Base(dictPath), time.Now())
|
||||
@ -24,49 +24,49 @@ func Sort(dictPath string, flag int) {
|
||||
// 打开文件
|
||||
file, err := os.OpenFile(dictPath, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 前缀内容和词库切片,前者原封不动写入,后者排序后写入
|
||||
prefixContents := make([]string, 0) // 前置内容切片
|
||||
contents := make([]lemma, 0) // 词库切片
|
||||
aSet := mapset.NewSet[string]() // 去重用的 set
|
||||
// 前缀内容切片、词库切片,前者原封不动写入,后者排序后写入
|
||||
prefixContents := make([]string, 0) // 前置内容
|
||||
contents := make([]lemma, 0) // 词库
|
||||
aSet := mapset.NewSet[string]() // 去重用的的 set
|
||||
|
||||
isMark := false
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
// mark 之前的写入 prefixContents
|
||||
|
||||
if !isMark {
|
||||
// mark 之前的写入 prefixContents
|
||||
prefixContents = append(prefixContents, line)
|
||||
if line == mark {
|
||||
if strings.HasPrefix(line, mark) {
|
||||
isMark = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// 分割为 text、code、weight
|
||||
// 分割为 text code weight
|
||||
parts := strings.Split(line, "\t")
|
||||
text, code, weight := parts[0], "", ""
|
||||
|
||||
// 检查分割长度
|
||||
if (flag == 1 || flag == 2 || flag == 3) && len(parts) != flag {
|
||||
fmt.Println("分割错误123:", line)
|
||||
if (_type == 1 || _type == 2 || _type == 3) && len(parts) != _type {
|
||||
log.Println("分割错误123")
|
||||
}
|
||||
if flag == 4 && len(parts) != 2 {
|
||||
fmt.Println("分割错误4:", line)
|
||||
if _type == 4 && len(parts) != 2 {
|
||||
fmt.Println("分割错误4")
|
||||
}
|
||||
|
||||
// 将 base 中注释了但没删除的词汇权重调为 0
|
||||
// 将 base 中注释了但没删除的词汇的权重调为 0
|
||||
if dictPath == BasePath && strings.HasPrefix(line, "# ") {
|
||||
parts[2] = "0"
|
||||
}
|
||||
|
||||
// mark 之后的,写入到 contents
|
||||
|
||||
// 自身重复的直接排除,不重复的写入
|
||||
switch flag {
|
||||
// 词库自身有重复内容则直接排除,不重复的写入到 contents
|
||||
switch _type {
|
||||
case 1: // 一列 【汉字】
|
||||
if aSet.Contains(text) {
|
||||
fmt.Println("重复:", line)
|
||||
@ -100,12 +100,13 @@ func Sort(dictPath string, flag int) {
|
||||
aSet.Add(text)
|
||||
weight, _ := strconv.Atoi(weight)
|
||||
contents = append(contents, lemma{text: text, weight: weight})
|
||||
default:
|
||||
log.Fatal("分割错误:", line)
|
||||
}
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// 排序:拼音升序、权重降序、最后直接按 Unicode 编码排序
|
||||
// 排序:拼音升序,权重降序,最后直接按 Unicode 编码排序
|
||||
sort.Slice(contents, func(i, j int) bool {
|
||||
if contents[i].code != contents[j].code {
|
||||
return contents[i].code < contents[j].code
|
||||
@ -119,7 +120,7 @@ func Sort(dictPath string, flag int) {
|
||||
return false
|
||||
})
|
||||
|
||||
// 准备写入
|
||||
// 准备写入,清空文件,移动指针到开头
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
@ -133,7 +134,7 @@ func Sort(dictPath string, flag int) {
|
||||
for _, line := range prefixContents {
|
||||
_, err := file.WriteString(line + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,21 +143,19 @@ func Sort(dictPath string, flag int) {
|
||||
for _, line := range contents {
|
||||
_, err := file.WriteString(line.text + "\t" + line.code + "\t" + strconv.Itoa(line.weight) + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 其他词库需要从一个或多个词库中去重后再写入
|
||||
if contains([]string{SogouPath, ExtPath, TencentPath}, dictPath) {
|
||||
var intersect mapset.Set[string] // 交集,有交集的就是重复的,去掉
|
||||
// ext tencent 词库需要从一个或多个词库中去重后再写入
|
||||
if dictPath == ExtPath || dictPath == TencentPath {
|
||||
var intersect mapset.Set[string] // 交集,有交集的就是重复的
|
||||
switch dictPath {
|
||||
case SogouPath:
|
||||
intersect = SogouSet.Intersect(BaseSet)
|
||||
case ExtPath:
|
||||
intersect = ExtSet.Intersect(BaseSet.Union(SogouSet))
|
||||
intersect = ExtSet.Intersect(BaseSet)
|
||||
case TencentPath:
|
||||
intersect = TencentSet.Intersect(BaseSet.Union(SogouSet).Union(ExtSet))
|
||||
intersect = TencentSet.Intersect(BaseSet.Union(ExtSet))
|
||||
}
|
||||
|
||||
for _, line := range contents {
|
||||
@ -164,22 +163,17 @@ func Sort(dictPath string, flag int) {
|
||||
fmt.Printf("%s 重复于其他词库:%s\n", strings.Split(path.Base(dictPath), ".")[0], line.text)
|
||||
continue
|
||||
}
|
||||
str := ""
|
||||
if flag == 3 { // sogou
|
||||
str = line.text + "\t" + line.code + "\t" + strconv.Itoa(line.weight) + "\n"
|
||||
} else if flag == 4 { // ext tencent
|
||||
str = line.text + "\t" + strconv.Itoa(line.weight) + "\n"
|
||||
}
|
||||
_, err := file.WriteString(str)
|
||||
s := line.text + "\t" + strconv.Itoa(line.weight) + "\n"
|
||||
_, err := file.WriteString(s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 外部词库或临时文件,只排序,不去重
|
||||
if !contains([]string{HanziPath, BasePath, SogouPath, ExtPath, TencentPath}, dictPath) {
|
||||
switch flag {
|
||||
if !contains([]string{HanziPath, BasePath, ExtPath, TencentPath}, dictPath) {
|
||||
switch _type {
|
||||
case 1:
|
||||
for _, line := range contents {
|
||||
_, err := file.WriteString(line.text + "\n")
|
||||
@ -211,6 +205,73 @@ func Sort(dictPath string, flag int) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := file.Sync(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取文件 sha1
|
||||
func getSha1(dictPath string) string {
|
||||
f, err := os.Open(dictPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
sha1Handle := sha1.New()
|
||||
if _, err := io.Copy(sha1Handle, f); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return hex.EncodeToString(sha1Handle.Sum(nil))
|
||||
}
|
||||
|
||||
// 排序后,如果文件有改动,则修改 version 日期,并输出 "...sorted"
|
||||
func updateVersion(dictPath string, oldSha1 string) {
|
||||
// 判断文件是否有改变
|
||||
newSha1 := getSha1(dictPath)
|
||||
if newSha1 == oldSha1 {
|
||||
fmt.Println()
|
||||
return
|
||||
}
|
||||
fmt.Println(" ...sorted")
|
||||
|
||||
// 打开文件
|
||||
file, err := os.OpenFile(dictPath, os.O_RDWR, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 修改那一行
|
||||
arr := make([]string, 0)
|
||||
sc := bufio.NewScanner(file)
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
if strings.HasPrefix(line, "version:") {
|
||||
s := fmt.Sprintf("version: \"%s\"", time.Now().Format("2006-01-02"))
|
||||
arr = append(arr, s)
|
||||
} else {
|
||||
arr = append(arr, line)
|
||||
}
|
||||
}
|
||||
|
||||
// 重新写入
|
||||
err = file.Truncate(0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = file.Seek(0, 0)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, line := range arr {
|
||||
_, err := file.WriteString(line + "\n")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = file.Sync()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -1,3 +1,4 @@
|
||||
话碴
|
||||
塞普路斯
|
||||
东蒂汶
|
||||
苏利南
|
@ -1,6 +1,16 @@
|
||||
# 含有需要注音的字的列表:
|
||||
# 例如在 ext tencent 无注音的词库中,检测到词库中有含有「伎俩」的词汇,但是没有注音,
|
||||
# 列出来,手动注音放到 main 中。
|
||||
# 需要进行注音的字词
|
||||
欻
|
||||
芫
|
||||
芾
|
||||
茈
|
||||
荑
|
||||
莨
|
||||
裨
|
||||
贲
|
||||
趵
|
||||
蹊
|
||||
𪨊
|
||||
沓
|
||||
扒拉
|
||||
伽蓝
|
||||
穆棱
|
||||
@ -16,11 +26,9 @@
|
||||
大王
|
||||
乐陵
|
||||
乐亭
|
||||
欻
|
||||
伎俩
|
||||
万俟
|
||||
会计
|
||||
# 偻
|
||||
龟兹
|
||||
拱券
|
||||
单于
|
||||
@ -94,7 +102,6 @@
|
||||
溃脓
|
||||
澹台
|
||||
瀑河
|
||||
# 炅
|
||||
炮烙
|
||||
犍为
|
||||
番禺
|
||||
@ -126,14 +133,9 @@
|
||||
怨艾
|
||||
自艾
|
||||
艾安
|
||||
芫
|
||||
芾
|
||||
茈
|
||||
荑
|
||||
荸荠
|
||||
莎草
|
||||
莘莘
|
||||
莨
|
||||
落枕
|
||||
落实
|
||||
落色
|
||||
@ -143,7 +145,6 @@
|
||||
慰藉
|
||||
蕴藉
|
||||
蚌埠
|
||||
裨
|
||||
匕首见
|
||||
匕见
|
||||
解池
|
||||
@ -156,10 +157,7 @@
|
||||
说客
|
||||
句读
|
||||
冠豸山
|
||||
贲
|
||||
趑趄
|
||||
趵
|
||||
蹊
|
||||
迫击
|
||||
铅山
|
||||
饼铛
|
||||
@ -210,7 +208,6 @@
|
||||
没人
|
||||
还好
|
||||
联系
|
||||
𪨊
|
||||
沓
|
||||
奇高
|
||||
奇迹
|
||||
了了
|
@ -1,61 +0,0 @@
|
||||
# scel2txt
|
||||
|
||||
搜狗细胞词库转鼠须管(Rime)词库,使用 Python3 实现
|
||||
|
||||
## 使用
|
||||
|
||||
将从[搜狗官方词库网站](https://pinyin.sogou.com/dict/)下载的 `*.scel` 文件放入 `scel` 文件夹,然后运行
|
||||
|
||||
```shell
|
||||
python3 scel2txt.py
|
||||
```
|
||||
|
||||
## 生成的文件
|
||||
|
||||
* 后缀为 .txt 的同名词库文件
|
||||
* 自动合并所有 *.txt 文件到 `luna_pinyin.sogou.dict.yaml`
|
||||
|
||||
|
||||
## 搜狗细胞词库(scel格式文件) 格式说明
|
||||
|
||||
按照一定格式保存的 Unicode 编码文件,其中每两个字节表示一个字符(中文汉字或者英文字母)。
|
||||
|
||||
主要包括两部分:
|
||||
|
||||
1. 全局拼音表,在文件中的偏移值是 0x1540+4, 格式为 (py_idx, py_len, py_str)
|
||||
- py_idx: 两个字节的整数,代表这个拼音的索引
|
||||
- py_len: 两个字节的整数,拼音的字节长度
|
||||
- py_str: 当前的拼音,每个字符两个字节,总长 py_len
|
||||
|
||||
2. 汉语词组表,在文件中的偏移值是 0x2628 或 0x26c4, 格式为 (word_count, py_idx_count, py_idx_data, (word_len, word_str, ext_len, ext){word_count}),其中 (word_len, word, ext_len, ext){word_count} 一共重复 word_count 次, 表示拼音的相同的词一共有 word_count 个
|
||||
- word_count: 两个字节的整数,同音词数量
|
||||
- py_idx_count: 两个字节的整数,拼音的索引个数
|
||||
- py_idx_data: 两个字节表示一个整数,每个整数代表一个拼音的索引,拼音索引数
|
||||
- word_len:两个字节的整数,代表中文词组字节数长度
|
||||
- word_str: 汉语词组,每个中文汉字两个字节,总长度 word_len
|
||||
- ext_len: 两个字节的整数,可能代表扩展信息的长度,好像都是 10
|
||||
- ext: 扩展信息,一共 10 个字节,前两个字节是一个整数(不知道是不是词频),后八个字节全是 0,ext_len 和 ext 一共 12 个字节
|
||||
|
||||
|
||||
## 目前已测试的词库
|
||||
|
||||
* [网络流行新词【官方推荐】](https://pinyin.sogou.com/dict/detail/index/4), 24923 个词
|
||||
* [最详细的全国地名大全](https://pinyin.sogou.com/dict/detail/index/1316), 114572 个词
|
||||
* [开发大神专用词库【官方推荐】](https://pinyin.sogou.com/dict/detail/index/75228), 430 个词
|
||||
* [中国高等院校(大学)大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/20647), 7192 个词
|
||||
* [宋词精选【官方推荐】](https://pinyin.sogou.com/dict/detail/index/3), 7297 个词
|
||||
* [成语俗语【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15097), 46785 个词
|
||||
* [计算机词汇大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15117), 10300 个词
|
||||
* [论语大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/22406), 2907 个词
|
||||
* [歇后语集锦【官方推荐】](https://pinyin.sogou.com/dict/detail/index/22418), 1926 个词
|
||||
* [数学词汇大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15202), 15992 个词
|
||||
* [物理词汇大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15203), 13107 个词
|
||||
* [中国历史词汇大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15130), 20526 个词
|
||||
* [饮食大全【官方推荐】](https://pinyin.sogou.com/dict/detail/index/15201), 6918 个词
|
||||
* [上海市城市信息精选](https://pinyin.sogou.com/dict/detail/index/19430), 37757 个词
|
||||
* [linux少量术语](https://pinyin.sogou.com/dict/detail/index/225), 136 个词
|
||||
|
||||
## 参考资料
|
||||
|
||||
1. [scel2mmseg](https://raw.githubusercontent.com/archerhu/scel2mmseg/master/scel2mmseg.py)
|
||||
2. [scel-to-txt](https://raw.githubusercontent.com/xwzhong/small-program/master/scel-to-txt/scel2txt.py)
|
@ -1,168 +0,0 @@
|
||||
"""
|
||||
搜狗细胞词库转鼠须管(Rime)词库
|
||||
|
||||
搜狗的 scel 词库是按照一定格式保存的 Unicode 编码文件,其中每两个字节表示一个字符(中文汉字或者英文字母),主要两部分:
|
||||
|
||||
1. 全局拼音表,在文件中的偏移值是 0x1540+4, 格式为 (py_idx, py_len, py_str)
|
||||
- py_idx: 两个字节的整数,代表这个拼音的索引
|
||||
- py_len: 两个字节的整数,拼音的字节长度
|
||||
- py_str: 当前的拼音,每个字符两个字节,总长 py_len
|
||||
|
||||
2. 汉语词组表,在文件中的偏移值是 0x2628 或 0x26c4, 格式为 (word_count, py_idx_count, py_idx_data, (word_len, word_str, ext_len, ext){word_count}),其中 (word_len, word, ext_len, ext){word_count} 一共重复 word_count 次, 表示拼音的相同的词一共有 word_count 个
|
||||
- word_count: 两个字节的整数,同音词数量
|
||||
- py_idx_count: 两个字节的整数,拼音的索引个数
|
||||
- py_idx_data: 两个字节表示一个整数,每个整数代表一个拼音的索引,拼音索引数
|
||||
- word_len:两个字节的整数,代表中文词组字节数长度
|
||||
- word_str: 汉语词组,每个中文汉字两个字节,总长度 word_len
|
||||
- ext_len: 两个字节的整数,可能代表扩展信息的长度,好像都是 10
|
||||
- ext: 扩展信息,一共 10 个字节,前两个字节是一个整数(不知道是不是词频),后八个字节全是 0,ext_len 和 ext 一共 12 个字节
|
||||
|
||||
参考资料
|
||||
1. https://raw.githubusercontent.com/archerhu/scel2mmseg/master/scel2mmseg.py
|
||||
2. https://raw.githubusercontent.com/xwzhong/small-program/master/scel-to-txt/scel2txt.py
|
||||
"""
|
||||
import struct
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def read_utf16_str(f, offset=-1, len=2):
|
||||
if offset >= 0:
|
||||
f.seek(offset)
|
||||
string = f.read(len)
|
||||
return string.decode('UTF-16LE')
|
||||
|
||||
|
||||
def read_uint16(f):
|
||||
return struct.unpack('<H', f.read(2))[0]
|
||||
|
||||
|
||||
def get_hz_offset(f):
|
||||
mask = f.read(128)[4]
|
||||
if mask == 0x44:
|
||||
return 0x2628
|
||||
elif mask == 0x45:
|
||||
return 0x26c4
|
||||
else:
|
||||
print("不支持的文件类型(无法获取汉语词组的偏移量)")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_dict_meta(f):
|
||||
title = read_utf16_str(f, 0x130, 0x338 - 0x130)
|
||||
category = read_utf16_str(f, 0x338, 0x540 - 0x338)
|
||||
desc = read_utf16_str(f, 0x540, 0xd40 - 0x540)
|
||||
samples = read_utf16_str(f, 0xd40, 0x1540 - 0xd40)
|
||||
return title, category, desc, samples
|
||||
|
||||
|
||||
def get_py_map(f):
|
||||
py_map = {}
|
||||
f.seek(0x1540+4)
|
||||
|
||||
while True:
|
||||
py_idx = read_uint16(f)
|
||||
py_len = read_uint16(f)
|
||||
py_str = read_utf16_str(f, -1, py_len)
|
||||
|
||||
if py_idx not in py_map:
|
||||
py_map[py_idx] = py_str
|
||||
|
||||
# 如果拼音为 zuo,说明是最后一个了
|
||||
if py_str == 'zuo':
|
||||
break
|
||||
return py_map
|
||||
|
||||
|
||||
def get_records(f, file_size, hz_offset, py_map):
|
||||
f.seek(hz_offset)
|
||||
records = []
|
||||
while f.tell() != file_size:
|
||||
word_count = read_uint16(f)
|
||||
py_idx_count = int(read_uint16(f) / 2)
|
||||
|
||||
py_set = []
|
||||
for i in range(py_idx_count):
|
||||
py_idx = read_uint16(f)
|
||||
if (py_map.get(py_idx, None) == None):
|
||||
return records
|
||||
py_set.append(py_map[py_idx])
|
||||
py_str = " ".join(py_set)
|
||||
|
||||
for i in range(word_count):
|
||||
word_len = read_uint16(f)
|
||||
word_str = read_utf16_str(f, -1, word_len)
|
||||
|
||||
# 跳过 ext_len 和 ext 共 12 个字节
|
||||
f.read(12)
|
||||
records.append((py_str, word_str))
|
||||
return records
|
||||
|
||||
|
||||
def get_words_from_sogou_cell_dict(fname):
|
||||
with open(fname, 'rb') as f:
|
||||
hz_offset = get_hz_offset(f)
|
||||
|
||||
(title, category, desc, samples) = get_dict_meta(f)
|
||||
#print("title: %s\ncategory: %s\ndesc: %s\nsamples: %s" %
|
||||
# (title, category, desc, samples))
|
||||
|
||||
py_map = get_py_map(f)
|
||||
|
||||
file_size = os.path.getsize(fname)
|
||||
words = get_records(f, file_size, hz_offset, py_map)
|
||||
return words
|
||||
|
||||
|
||||
def save(records, f):
|
||||
records_translated = list(map(lambda x: "%s\t%s" % (
|
||||
x[1], x[0]), records))
|
||||
f.write("\n".join(records_translated))
|
||||
return records_translated
|
||||
|
||||
|
||||
def main():
|
||||
# 将要转换的词库添加在 scel 目录下
|
||||
scel_files = list(filter(lambda x: x.endswith('.scel'), [
|
||||
i for i in os.listdir("./scel")]))
|
||||
|
||||
dict_file = "luna_pinyin.sogou.dict.yaml"
|
||||
dict_file_content = []
|
||||
dict_file_header = """# Rime dictionary
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Sogou Pinyin Dict - 搜狗细胞词库
|
||||
#
|
||||
# https://pinyin.sogou.com/dict/
|
||||
#
|
||||
# 包括:
|
||||
#
|
||||
%s
|
||||
#
|
||||
|
||||
---
|
||||
name: luna_pinyin.sogou
|
||||
version: "1.0"
|
||||
sort: by_weight
|
||||
use_preset_vocabulary: true
|
||||
...
|
||||
"""
|
||||
sougo_dict_name_list = list(
|
||||
map(lambda x: "# * %s" % x.replace(".scel", ""), scel_files))
|
||||
dict_file_content.append(dict_file_header % "\n".join(sougo_dict_name_list))
|
||||
|
||||
for scel_file in scel_files:
|
||||
records = get_words_from_sogou_cell_dict(
|
||||
os.path.join("./scel", scel_file))
|
||||
print("下载搜狗流行词 %s: %s 个词" % (scel_file, len(records)))
|
||||
with open(os.path.join("./out", scel_file.replace(".scel", ".txt")), "w") as fout:
|
||||
dict_file_content.extend(save(records, fout))
|
||||
# print("-"*80)
|
||||
|
||||
# print("合并后 %s: %s 个词" % (dict_file, len(dict_file_content) - 1))
|
||||
with open(os.path.join("./out", dict_file), "w") as dictfout:
|
||||
dictfout.write("\n".join(dict_file_content))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -13,5 +13,5 @@ import_tables:
|
||||
- cn_dicts/others # 一些杂项
|
||||
|
||||
# 建议把扩展词库放到下面,有重复词条时,最上面的权重生效
|
||||
# - cn_dicts/my_dict
|
||||
# - cn_dicts/mydict
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user