拼写运算详解

佛振 chen.sst@gmail.com

2012-02-14

拼写运算

「重现世间无匹好兵器,一发招覆雨惊天地。」

Rime输入法独门绝活之「拼写运算」,是按规则改写编码的形式、实现多种定制功能的技术。

概念

先来介绍本文所使用的术语:

功能

传统的中文输入法是基于码表的,通过键盘输入特定字母序列,获得与该编码对应的文字。
而大多数编码方案,都不会用尽编码空间内的所有编码;与字符集内的文字无对应的编码,就在编码空间中形成空位。
为了提高输入效率,输入法会利用编码空间中的空位,编制简码、容错码等衍生编码,以在尽量多的场合为用户提供有意义的候选文字。

在某些输入方案里,简码、容错码可以从源码表按照一定规则产生。
如:汉语拼音输入法中的简拼,取拼音音节的首字母,也可取以双字母表示的声母zh、ch、sh。
这是因为编码方案所遵循的语言学原理,决定了拼音音节在编码空间内的分布及留下的空位,呈某种规则的形式。
故,产生简码、容错码的规则是与输入方案相关的,一款通用的输入法软件要以与编码方案相适应的方式生成这些衍生编码。

拼写运算,提供了描述产生式规则的能力!

为了提供多样化的输入体验,Rime可借由一份码表制作多款输入方案。
譬如:注音符号、汉语拼音这两套注音方案是为相同音系设计的(忽略地区间字音标准的差异)。
今有一份注音码表,按一定对应规则将注音转换为汉语拼音,可使注音、汉语拼音,甚至还有基于汉语拼音的双拼等输入方案复用同一部词典。

拼写运算,提供为输入方案重构拼写法的能力!

此外,改变编码回显的样式、按特定规则生成词组编码……拼写运算也可用来实现此等需要定制能力的算法。

原理与实现

拼写运算,藉助正则表达式实现其字符串处理能力。
进一步,利用数学知识,构造出建立在输入法编码集合上的代数系统。

拼写运算实现为Rime程序库中的一套算法,可从Rime配置文件导入一组算式,执行规定的计算步骤。
运算步骤以YAML字符串列表的形式定义;每个列表项为描述一项运算的算式。
算式中包含的正则表达式,遵照Perl正则表达式的语法规范。

拼写运算的算式

格式为:<运算子><分隔符><参数1><分隔符><参数2><分隔符>...
分隔符为单个ASCII字符,通常用符号或空白字符。
举例:
xlit/abc/ABC/
上式中,运算子为 xlit(转写),分隔符为“/”,有两个参数 "abc"、"ABC"
如果参数中不包含空格,也可写作:
xlit abc ABC
注意:作为分隔符的字符不能在参数中出现;不同于Perl的 s/\//\\/ 语法:拼写运算式不支持在参数中将用作分隔符的字符用“\”转义表示。

拼写运算的运算子

* 转写/Transliteration : 依次将拼写中见于<左字母表>的字符替换为<右字母表>对应位置的字符。左、右字母表应包含相同数目的Unicode字符。

 格式:xlit/<左字母表>/<右字母表>/
 实例:算式 xlit/abc/ABC/  运算元 abracadabra  结果 ABrACAdABrA
 
* 变形/Transformation : 若拼写(或其子串)与<模式>匹配,则将所匹配的部份改写为<替换式>;否则拼写保持不变。模式、替换式遵循Perl正则表达式语法。

 格式:xform/<模式>/<替换式>/
 实例:算式 xform/^([nl])ue$/$1ve/  运算元 nue  结果 nve
 效果:输入nve(lve)可以获得源码表中与编码nue(lue)对应的候选;输入nue(lue)无候选

* 消除/Erasion : 若拼写与<模式> 完 全 匹配,则将该拼写从有效拼写集合中消除。

格式:erase/<模式>/
实例:算式 erase/^.*\d$/  运算元 dang1  结果 带声调的拼音不再可用

* 派生/Derivation : 若对拼写做正则模式匹配、替换而获得了新的拼写,则有效拼写集合同时包含派生前后的拼写;否则仅保留原拼写。

 格式:derive/<模式>/<替换式>/
 实例一:算式 derive/^([nl])ue$/$1ve/  运算元 nue  结果 nve
 效果:输入nve或nue(lve或lue)均可获得源码表中与编码nue(lue)对应的候选

 实例二:算式 derive/^[nl](.*)$/l$1/  运算元 na  结果 la
 效果:输入la可获得源码表中与编码na、la对应的候选;输入na,候选仍为码表中编码为na的候选

* 模糊/Fuzzing : 执行派生运算;派生出的拼写将获得「模糊」属性,可设定将其用作构成词组的简码、但不用于输入单字。

 格式:fuzz/<模式>/<替换式>/
 实例:算式 fuzz/^([a-z]).+([a-z])$/$1$2/
 效果:以首、尾码为多字母音节码的构词码。
     注:需配合 script_translator 的选项 `translator/strict_spelling: true` 方可限定该拼写不用于输入单字。

* 缩略/Abbreviation : 执行派生运算;派生出的拼写将获得「缩略」属性,会在音节切分时与通常的拼写做区分处理。

 格式:abbrev/<模式>/<替换式>/
 实例:算式 abbrev/^([a-z]).+$/$1/
 效果:以首字母为多字母音节码的缩写。

注解:

投影算法

在拼写法投影操作P[x,y,z]里,每项运算x, y, z作为投影的一个步骤,依次从作为运算元的拼写法中产生一套新的拼写法;
将拼写法投影用于构建拼写-编码映射时,用户的输入是随意的;而码表中,音节表是固定的集合A。

所以Rime选音节表A上的初始拼写法(A -> A)为投影的运算元,逐步推导出映射到音节表A的有效拼写集合B,即所求的拼写法(B -> A)。

算法:

记音节表为A,拼写运算为序列[x,y,z],该投影的结果记为 P[x,y,z](A -> A)
Sa = { a -> a | for a in A } = (A -> A)
Sx = P<x>(Sa) = { x(a) -> a | for (a -> a) in (A -> A) } = (B -> A)
Sy = P<y>(Sx) = { y(b) -> a | for (b -> a) in (B -> A) } = (C -> A)
Sz = P<z>(Sy) = { z(c) -> a | for (c -> a) in (C -> A) } = (D -> A)
P[x,y,z](Sa) = Sz

在Rime输入方案中的用法

一例:仓颉输入方案(cangjie5.schema.yaml),在编码区回显仓颉字母

translator:
  preedit_format:
    - xlit|abcdefghijklmnopqrstuvwxyz|日月金木水火土竹戈十大中一弓人心手口尸廿山女田难卜符|

一例:朙月拼音(luna_pinyin.schema.yaml),显示拼音字母“ü”

translator:
  preedit_format:
    - xform/([nl])v/$1ü/

这一处,拼写运算的作用对象是编码回显区的拼音串,串中可能包含多个拼音音节,并已经自动插入了隔音符号。
为了替换该拼音段中所有匹配的字母,模式中并未用锚点匹配音节的头尾位置。

一例:朙月拼音(luna_pinyin.schema.yaml),定义简拼、容错拼写。

speller:
  algebra:
    - abbrev/^([a-z]).+$/$1/          # 简拼(首字母)
    - abbrev/^([zcs]h).+$/$1/         # 简拼(zh, ch, sh)
    - derive/^([nl])ve$/$1ue/         # 设 nue = nve, lue = lve 
    - derive/ui$/uei/                 # 设 guei = gui,...
    - derive/iu$/iou/                 # 设 jiou = jiu,...
    - derive/([aeiou])ng$/$1gn/       # 容错 dagn = dang,...
    - derive/ong$/on/                 # 容错 zhonguo = zhong guo
    - derive/ao$/oa/                  # 容错 hoa = hao,...
    - derive/([iu])a(o|ng?)$/a$1$2/   # 容错 tain = tian,...

编译输入方案时,将运用这组运算规则完成音节表上的投影,求得可解析为音节代码的有效拼写集合;
输入过程中,这组有效拼写决定着输入码的音节切分方式。

一例:在拼音输入法中定义模糊音 zh=z, ch=c, sh=s, n=l, en=eng, in=ing

speller:
  algebra:
    - derive/^([zcs])h/$1/
    - derive/^([zcs])([^h])/$1h$2/
    - derive/^n/l/
    - derive/^l/n/
    - derive/([ei])n$/$1ng/
    - derive/([ei])ng$/$1n/
    # 模糊音定义先于简拼定义,可令简拼支持以上模糊音
    - abbrev/^([a-z]).+$/$1/
    - abbrev/^([zcs]h).+$/$1/

工具

除Rime输入法主程序外,拼写运算还用于:

讨论

拼写运算技术及应用技巧,你有好的话题,请在本页或 Rime 官网讨论页 留言。