Skip to content

Latest commit

 

History

History
145 lines (105 loc) · 5.18 KB

standardize.md

File metadata and controls

145 lines (105 loc) · 5.18 KB

偏旁规范化以及去重

偏旁规范化, 指的是让辅助码更符合 zrm2000 的映射规则, 以此降低一个字同时对应多组辅助码的问题, 从而减少重码. 对于大多数汉字, 自然码的辅助码取决于部首和偏旁.

  • 部首偏旁 的区别 --- 以'高'为例
  • 如果一个字由部首(可以理解为"主要"的偏旁)和其它部分(也是偏旁), "自然码+辅助码"的第三码取做部首, 第四码取为最后一个偏旁.
  • 如果一个字本身就是部首, 即独体字, 不能进一步拆分出部件, 只能由笔画构成. "自然码+辅助码"的第三码是第一笔, 第四码是最后一笔.

部首和偏旁在zrm2000方案中对应的辅助码和键位, 可参考以下链接:

  1. 官方链接: 自然码2000手册
  2. 民间整理:

如果一个文件(比如 zrm-pinyin.dict.yaml) 存在一个字同一发音多个辅码的情况. 例如该 dict 的 旁的辅助码同时有 日=o日=r, 这造成每个带 字旁的字都有双重冗余, 比如同时存在 星=xy;ru星=xy;ou. 对此, 可以通过 convert.py 将辅助码统一到标准的 日=o, 即只留下 星=xy;ou, 并且移除重复条目.

zrm_pinyin.unique_fm.dict.yaml 则存在一个偏旁对应不同辅码的情况. 例如, 该 dict 的 旁的辅助码在 日=o日=r 之间随机变化 (该 dict 中 昙=tj;oy, 星=xy;ru≠xy;ou), 这将导致我们输入 tj;oy 得到 , 却无法输入 xy;ou 得到 , 导致每次输入一个 字旁的字之前, 都得先猜一猜究竟是 日=o 还是 日=r, 非常影响效率. 对此, 可以通过 convert.py 将辅助码统一到标准的 日=o, 以后输入 字旁的字就不用猜辅助码了, 都是 日=o.

具体过程:

  1. resh3函数对zrm-pinyin.dict.yaml修改, 将辅助码重新映射以符合规范(例如xy;ru -> xy;ou), 输出至文件zrm-pinyin.temp.dict.yaml.
  2. rm_repeat函数对zrm-pinyin.temp.dict.yaml操作, 对相邻行且重复的条目进行去重, 输出至文件zrm-pinyin.wanted.dict.yaml.
  3. 删除(或备份)原来的zrm-pinyin.dict.yaml, 再手动重命名zrm-pinyin.wanted.dict.yaml -> zrm-pinyin.dict.yaml, rime就会使用这个新的字典.

1. 拆字准备

通过pip安装cnradical, 这个软件包用于获取汉字的部首.

1.1 有明显部首的字

cnradical可以正确地拆出大多数部首.

import sys
from cnradical import Radical, RunOption 
radical = Radical(RunOption.Radical) #获取偏旁 
# 测试部首结果
print(radical.trans_ch('伍'))
print(radical.trans_ch('变'))
print(radical.trans_ch('充'))
亻
又
亠
print(radical.trans_ch('膀'))
print(radical.trans_ch('臂'))
print(radical.trans_ch('瞥'))
print(radical.trans_ch('撻'))
print(radical.trans_ch('循'))
月
月
目
扌
彳

1.2 独体字

一般是部首汉字, 如:“金木水火土辶皿马皮日月目衣耳”等. 独体字全部看成部首, 不能进一步拆分出部件, 只能由笔画构成. 对于这类字, cnradical可能不准.

radical.trans_ch('由')
'田'

1.3 ”拆不动“的字

  • 独体字, 自身即部首.
  • cnradical未收录的字, 输出自不准确.
print(radical.trans_ch('一'))
print(radical.trans_ch('禾'))
print(radical.trans_ch('鯈'))
print(radical.trans_ch('擜'))
一
禾
魚
扌

非汉字:

print(radical.trans_ch('a'))
print(radical.trans_ch(' '))
print(radical.trans_ch('\t'))
print(radical.trans_ch('\n'))
None
None
None
None

2. 构造用于分析文件的函数

convert.py 中定义了如下两个函数:

  • resh3() 函数用于规范化第三码(部首辅助码). 目前暂未考虑第四码, 因为"最后一个偏旁"很难从程序上消除模糊性, 为了避免更多的模棱两可, 所有字的第四码一律不做修改.

  • rm_repeat() 函数用于去除 行数相差小于或等于10行 且 完全重复 的编码条目.

3. 分析文件

convert.py 中的如下行将字典 FILE_IN 调整部首码并输出为临时文件

resh3(FILE_IN, 'temp.yaml')   

而下面一行则用于去重. 输入上一步的临时文件, 去重之后输出覆盖原文件. 这样得到有“更符合规范”的码, 且无重复条目.

rm_repeat('temp.yaml', FILE_IN)

经过上述过程, 第三码(部首/首个偏旁)得到了部分纠正, 而第四码(末个偏旁)未被调整.

所以肯定仍然存在不准确的码. 欢迎提issue, 以便完善筛选部首的函数, 以及为第四码的错码找规律.

4. 可能有错的编码

  • 独体字, 如前所述, cnradical拆不准.
  • 生僻字, cnradical 拆不准或拆不了.
  • 极少比例的第四码可能不正确, 因为cnradical只拆分部首.