hoss
新手上路
新手上路
  • 社区居民
  • 忠实会员
阅读:154回复:3

小小秘笈㈠㊦:无编码词条自动造词的小小不足

楼主#
更多 发布于:2019-10-11 18:13
小小秘笈㈠㊦:无编码词条自动造词的小小不足
——看Excel和TextPro如何实现码表精准造词


在小小输入法平台上移植源自台湾输入法的过程中,总会遇到的各种不适,主要表现为两岸输入法的设计理念不同。比如传统输入法生成器和小小输入法平台只能实现一律等长码的自动造词,尽管可满足大陆输入法普遍要求,却与一些台湾输入法的造词习惯有抵触。实际上,具体到构词规则,大陆输入法和台湾输入法普遍存在两个不同之处:
  • 首次码与首尾码
  • 等长码与非等长码
构词规则:首次码与首尾码

不管临时造词或批量造词,输入法生成器根据码本的构词规则自动给两字以上词条编码。然而构词规则存在一些短板,例如不能指定某字的最后一码作为编码。对于二三字词条,大陆制作的输入法习惯采用首次码参与词条编码,而台湾制作的输入法则习惯采用首尾码参与词条编码。四字以上词条则不涉及首次码或首尾码问题,因为每个字只有单码参与词条编码(可以是首码,也可以是尾码)。显然,要解决二三字词条指定首尾码参与编码,只能在码本中的每个汉字和编码之后添加构词码,其中汉字和编码之间没有空格,而编码和构词码有一个空格。构词码默认为空,可以不填。

这里给出实例(码本为简体大易输入法,构词码取首尾码):
阿peoj pj
爸8xrc 8c

如果要创建“阿爸”一词,构词规则还是按照一般二字词构词规则填写:
ce2=p11+p12+p21+p22

无构词码,“阿爸”一词为pe8x;有构词码,“阿爸”一词为pj8c。

因此,借助于构词码可以实现台湾输入法习惯的首尾码造词。其实构词码主要用来指定多码字(拼音类为多音字)参与构词时所选用的编码,如全拼输入法“的”有两个读音“de di”,码表可指定“de”为构词码。
的 de
的 di de

至于构词码要如何添加到码本呢?一般用Excel或文本操作可以轻松实现。

小小输入法平台无需通过构词码的设置,就可以直接了当在构词规则中指定尾码,即用“-1”表示:
code_e2=p11+p1-1+p21+p2-1
code_e3=p11+p21+p31+p3-1
code_a4=p11+p21+p31+n1-1

上述构词规则描述了简体大易输入法二三字词条分别取码“首尾+首尾”和“首+首+首尾”之外,四字以上词条取码“首+首+首+末尾”明显与大陆输入法习惯“首+首+首+末首”末字取首码不同,这里末字径直取尾码。两岸输入法习惯并无优劣之分,只是用户长期沿用下来感觉适用而已。

构词规则:等长码与非等长码

按大陆输入法习惯,码本所有的字全码一般上不少于两码,这样设计是为了将珍贵的一码字、二码字和三码字保留给高频字,称为一级简码、二级简码和三级简码。如此一来,少于四码的字必须另作安排,如五笔就有所谓键名字、成字根字、末笔字型交叉识别码等特意加长码长的设计。由此衍生出的构词码基本维持两码以上,这样可保证二三字词的码长均为四码。反观台湾输入法习惯则是维持自然码长,原来多少码就编多少码,很少有特意加长码长的设计,大多数也没有简码的概念。如此一来,台湾输入法构词时二三字词会碰上单码字,如简体大易输入法的“火y、山w、水x、手g、工r、夫v”都是单码字,可凑成“火山yw”、“山水wx”、“水手xg”、“水工xr”、“手工gr”、“工夫rv”等词,其二字词码长也只有两码。同样地,如果三字词的第三个字恰好属于单码字,其码长也只有三码,如“峨眉山whw”、“地下水fex”、“突击手mfg”、“教职工fpr”、“硬功夫qrv”等词。更多的是二字词中包含一个单码字,其码长则为三码字,如“灯火yjy”、“登山0uw”、“废水c.x”、“到手eng”、“出工wwr”、“夫妇vlr”等词。由于单码字参与二三字词条造词的码长属于非等长码,不管输入法生成器的构词码还是小小输入法平台的指定尾码都一律重复输出,无法真正产生单码参与编码,造成二三字词条都是等长四码。

对于非等长码的造词要求,我们可以分别借助Excel和TextPro两套相互独立的方案完成码表精确操作,实现非等长码的批量造词。

码表预处理

与上一篇处理五笔主码表一样,我们必须去除掉简体大易码表的容错码。首先对码表单字进行排序,筛选出多码字(图1),然后在全新表单里贴出多码字,分两次输入判断简体大易多码字公式,再逐个把经过检验的容错码集中转移到jtdy2.txt文件即可,留下全码和简码作为主码表jtdy.txt(图2)。

描述:图1

图片:简体大易单字.jpg

图1


描述:图2

图片:简体大易多码字.jpg

图2


判断简体大易多码字公式显然不同于上一篇判断五笔多码字公式,原因是简体大易输入法的简码只来源于三码以上的全码字(固定取首尾两码)而不会来源于容错码,所以简码是分辨全码和容错码的重要依据。唯简码排列位置既可能处于全码或容错码之上,也可能处于全码或容错码之下,故需要分两次输入公式以完成判断流程——第一次粗分简码和全码/容错码,第二次细分全码和容错码。
C2=IF(LEN(B1)=2,IF(OR(B2=LEFT(B3)&RIGHT(B3),B2=LEFT(B1)&RIGHT(B1)),"简码","全码/容错码"),"全码/容错码")
D2=IF(C2="全码/容错码",IF(OR(AND(A2=A1,C1="简码",B1=LEFT(B2)&RIGHT(B2)),AND(A2=A3,C3="简码",B3=LEFT(B2)&RIGHT(B2))),"全码","容错码"),"简码")

非等长构词码解决方案一:Excel

首先,将码本的全码和单字分别读入Excel工作表的A列和B列,C列利用公式“=LEFT(A2)”列出首码,D列则利用条件判断式“=IF(LEN(A2)>1,LEFT(A2)&RIGHT(A2),LEFT(A2))”根据全码码长列出非等长码的构词码,过后分别双击C2列和D2列右下角的黑色小方块,这时鼠标变成黑十字,C列和D列开始自动生成公式结果。

接下来,粘贴二字词于E列,填入以下公式于F列提取二字词编码:
=VLOOKUP(LEFT(E2),$B$2:$D$7382,3,)&VLOOKUP(RIGHT(E2),$B$2:$D$7382,3,)

另外,再设立G列二字词少于四码,其公式如下:
=IF(LEN(F2)<4,F2,"")

过后分别双击F2列和G2列右下角的黑色小方块,这时鼠标变成黑十字,F列和G列开始自动生成公式结果。

同样地,粘贴三字词于H列,填入以下公式于I列提取三字词编码:
=VLOOKUP(LEFT(H2),$B$2:$D$7382,2,)&VLOOKUP(MID(H2,2,1),$B$2:$D$7382,2,)&VLOOKUP(RIGHT(H2),$B$2:$D$7382,3,)

另外,再设立J列三字词少于四码,其公式如下:
=IF(LEN(I2)<4,I2,"")

过后分别双击I2列和J2列右下角的黑色小方块,这时鼠标变成黑十字,I列和J列开始自动生成公式结果。

这里最费解的是F列和I列的VLOOKUP函数,不妨花些笔墨加以说明:VLOOKUP可以填入四个参数,即要查找的值、要在其中查找值的区域、区域中包含返回值的列号、近似匹配或精确匹配。最后一个参数为可选项,唯前面逗号不可省略。
  • 要查找的值:LEFT(E2)和RIGHT(E2),即二字词内容(本例中LEFT(E2)值为单字“爱”,RIGHT(E2)值为单字“戴”)。
  • 要在其中查找值的区域:$B$2:$D$7382,锁定单字、首码和构词码共三列的区域(如果写成B:D则是逐行查找而非锁定区域从顶到底查找),其中要查找的值要求位于区域最左列。
  • 区域中包含返回值的列号:2,即C列的首码(仅用于三字词前两字编码);3,即D列的构词码(分别用于二字词全部编码和三字词末字编码)。
  • 近似匹配或精确匹配:TRUE或FALSE,也可写成1或0。默认值为TRUE或1,即近似匹配。
整个工作表可划分为三个区块,分别为源码表区块(A至D列)、二字词区块(E至G列)和三字词区块(H至J列),其中黄色部分属于Excel公式生成的结果(图3)。最后我们可暂时隐藏F列和I列后方便选择输出二字词的E列和G列以及三字词的H列和J列,这就是二字词和三字词分词库所需的结果(图4)。只是为适应小小平台要求码表先码后字,二字词的E列和G列以及三字词的H列和J列还要进一步调换顺序。至此二字词和三字词分词库工作结束。

描述:图3

图片:Jtdybox.jpg

图3


描述:图4

图片:Jtdybox2.jpg

图4


非等长构词码解决方案二:TextPro
如果上述Excel方案的VLOOKUP函数有点费解,那么TextPro方案的自定义替换表就很容易理解,简直是专门为码表精准造词而设。所谓自定义替换表,就是一张把某个字符串替换为另一个字符串的对照表,比如把汉字替换为拼音串或用数字带调的拼音串替换为真正带调字母的拼音串(如han4替换为hàn)。该替换表是一个文本文件,它的每一行指定一个替换关系。该行分成两栏,栏与栏之间用半角等号“=”分开。第一栏是源字符串,第二栏是目标字符串,近似先字后码的码表关系(图5)。

描述:图5

图片:简体大易构词表.jpg

图5

为此,我们打开简体大易码表,去掉表头描述部分、表中等号开头的非汉字编码部分和表尾简码部分,通过替换操作抽掉所有三四码中间一两个码,留下的首尾码就形成了简体大易构词码。由于自定义替换表的格式要求,源字符串和目标字符串的顺序还要调换,中间插入等号:
查找:(\~f).*(\~f) (\c)
替换:\3=\1\2

上述替换只匹配到两码字、三码字和四码字,独漏了单码字,所以还要对单码字进行调换顺序:
查找:(\~f) (\c)
替换:\2=\1

打开“设置→自定义替换表”菜单项,选中任一空行,点击“设置”按钮,打开上述简体大易构词码文件,就可以开始进行二字词编码替换(图6):
查找:^(\c)(\c)$
替换:\T3{\1}\T3{\2} \0

描述:图6

图片:简体大易构词表2.jpg

图6

由于三字词前两字只用到首码,末字才用到首尾码,通过正则表达式可以指定过滤尾码,无需另建简体大易首码的替换表。重新打开设置中的自定义替换表,点击“选项”按钮选中“正则表达式”,再点击“过滤”按钮输入“(\~f)(\~f?)”正则表达式(图7):
查找:^(\c)(\c)(\c)$
替换:\T3{\1}[1]\T3{\2}[1]\T3{\3} \0

描述:图7

图片:简体大易构词表3.jpg

图7
hoss
新手上路
新手上路
  • 社区居民
  • 忠实会员
沙发#
发布于:2019-10-18 20:41
分析与建议

  • 为应付台湾输入法造词要求首尾码构词而非首次码构词,传统输入法生成器勉强可以利用构词码解决,小小输入法平台则可以直截了当指定首尾码构词,显然略胜一筹。然而在面对非等长码构词的要求时,不管是传统输入法生成器还是小小输入法平台,两者都力有不逮。
  • 在码表预处理时,简体大易码表不像五笔码表可以依靠码长的自然排序来分辨全码、简码和容错码(因为简码与全码总是上下挨着的),而纯粹只能依靠简码来区分全码和容错码。当三者一起出现而且简码与全码之间横亘着容错码时,将导致全码和容错码弄混甚至全部被误判为容错码。看来,第一次粗分简码和全码/容错码的公式不够严谨,有待改进。
  • 我们在输出Excel和TextPro二三字词条时还要对满四码的过滤掉其编码,只保留那些少于四码的编码,固然一方面是有意突出小小输入法平台可以自动编码的功能,另一方面则是着眼于一旦单字编码有改动时无需再次为词条重新编码,始终保证词条编码准确有效,同时也减少词条文件的大小。
  • 其实小小输入法平台只需稍微改进构词规则算法,引进正则表达式的可有可无的重复指示符即问号(?),那么适用于简体大易的二三字词构词规则可以改写如下:
code_e2=p11+p1-1?+p21+p2-1?
code_e3=p11+p21+p31+p3-1?
就不用大费周章地展开上述两套非等长构词码的解决方案了。

  • 无论如何,为方便用户早日用上小小输入法平台的无编码词条自动造词的功能,在排除码表多码字的过程中无意中发现了通过Excel公式可以对码表中多码字的来源到底是全码、简码或容错码加以识别,算是一项意外收获。唯我本人并非Excel专家,在探索过程中都是先射箭后画靶,才鼓捣出分别适用于两岸较具有代表性的形码输入法的码表多码字自动识别公式。由于五笔和大易的取码规则都大相径庭,反映在码表多码字自动识别公式当然也就大异其趣,往后也许可以成为分析形码输入法码表结构的特征之一。

hoss
新手上路
新手上路
  • 社区居民
  • 忠实会员
板凳#
发布于:2019-11-01 16:18
经过提炼后,简体大易码表多码字溯源公式已完美实现辨识简码、全码和容错码
关键就是先找出B列码长列于C列,然后按A列和C列进行两级排序(见附图),这样就可强制规定多码字的简码位于全码或容错码之上。同时在辨识全码和容错码时,还需分别输入E2项和E3项,从E3项开始往下自动生成公式结果。值得一提的是E列偶尔会出双全码,那是正常的,因为不管全码还是容错码,其首尾码都与简码完全匹配。这只好留待人来做出判断,正如那些没有简码的多码字无从判断其为全码或容错码。

有关公式如下:
D1=IF(LEN(B1)=2,IF(OR(AND(A1=A2,B1=LEFT(B2)&RIGHT(B2)),AND(A1=A3,B1=LEFT(B3)&RIGHT(B3))),"简码","全码/容错码"),"全码/容错码")
E2=IF(D2="全码/容错码",IF(AND(A2=A1,D1="简码",B1=LEFT(B2)&RIGHT(B2)),"全码","容错码"),"简码")
E3=IF(D3="全码/容错码",IF(OR(AND(A3=A2,D2="简码",B2=LEFT(B3)&RIGHT(B3)),AND(A3=A1,D1="简码",B1=LEFT(B3)&RIGHT(B3))),"全码","容错码"),"简码")
hoss
新手上路
新手上路
  • 社区居民
  • 忠实会员
地板#
发布于:2019-11-01 16:18
附图:
游客

返回顶部