【求助】一个 Perl“模糊查询匹配”正则表达式的写法,应该如何写?

软件和网站开发以及相关技术探讨
回复
头像
yq-ysy
论坛版主
帖子: 4466
注册时间: 2008-07-19 12:44
来自: 广西(桂)南宁(邕)

【求助】一个 Perl“模糊查询匹配”正则表达式的写法,应该如何写?

#1

帖子 yq-ysy » 2020-03-03 22:47

我使用 Rime 根据自己编排的码表,已经成功做出了“单手笔顺输入法”,能用数字小键盘打出汉字和词组。
开源网址请参见:https://github.com/YQ-YSY/one-hand_Rime
现在我想使用 Rime 的 Speller 功能中 Algebra 的 fuzz 模糊派生运算,构成词组的简码,希望能以此提高词组的输入速度。
相关文档请参见: https://github.com/rime/home/wiki/SpellingAlgebra

其中说到:——拼寫運算實現爲Rime程序庫中的一套算法,可從Rime配置文件導入一組算式,執行規定的計算步驟。 運算步驟以YAML字符串列表的形式定義;每個列表項爲描述一項運算的算式。 算式中包含的正則表達式,遵照Perl正則表達式的語法規範。
模糊/Fuzzing : 執行派生運算;派生出的拼寫將獲得「模糊」屬性,可設定將其用作構成詞組的簡碼、但不用於輸入單字。
格式:fuzz/<模式>/<替換式>/
實例:算式 fuzz/^([a-z]).+([a-z])$/$1$2/
效果:以首、尾碼爲多字母音節碼的構詞碼。
实际应用到我的 Rime 配置文件 one_hand.schema.yaml 中,这个表达式应该怎么写?
即这个文件: https://github.com/YQ-YSY/one-hand_Rime ... chema.yaml
在第59~63行的后面,我现在是这样写的,但无效:

代码: 全选

speller:
  alphabet: 0123456789	 			# 用于编码的可输入字符
  delimiter: "." 				# 词组的每个字分隔符号
  algebra:
    - 'fuzz/^([^0-9]).+([^0-9])$/$1$2/' 	# 词组中的每个字仅取前二个码


例如,在词库码表文件 one_hand.schema.yaml 里已经有这三个词组:

代码: 全选

笔顺		3767.322138
输入法		773412.34.441954
笔顺输入法	3767.322138.773412.34.441954
第一步,我想在打词组时简化成“词组中的每一个字只需前二码”,即:

代码: 全选

笔顺		37.32
输入法		77.34.44
笔顺输入法	37.32.77.34.44
第二步,我想在打词组时能简化成“词组中的每一个字不限编码长度,也不限汉字个数”,即:

代码: 全选

笔顺 3.3		# (每个字最少开头一个码,多码不限,当然越多越准确)
输入法 773.34.4		# (词组有可能是二字、三字、四字,甚至更多的字)
笔顺输入法 3.32..44	# (只打“笔顺…法”首尾二字或三字即可匹配,不需要每个字都打完)
如果能实现上述的词组输入方法,那么“单手笔顺输入法”打字将会是飞一般的快!这不是猜测,而是已经有一个商业的输入法是这样做的了,我用过,所以知道这样打字特别快。(请参见“数字五笔输入法”官方网站:http://www.szwb.com/

还请各位大侠指教,我应该如何写这一个 fuzz 表达式?
头像
astolia
论坛版主
帖子: 6514
注册时间: 2008-09-18 13:11

Re: 【求助】一个 Perl“模糊查询匹配”正则表达式的写法,应该如何写?

#2

帖子 astolia » 2020-03-04 0:35

你写的正则式的意思是,取第一个和最后一个非0~9的字符。自然什么也匹配不到
不知道它这个algebra是针对已经被分割了的单字编码,还是针对整个词组编码
如果是前者,取前两码应该就是

代码: 全选

'fuzz/^([0-9]{2})[0-9]+$/$1/'
由于单一正则只会产生单一输出,所以要实现你第二步,必须写多个fuzz式

代码: 全选

'fuzz/^([0-9]{1})[0-9]+$/$1/' #单字前1码
'fuzz/^([0-9]{2})[0-9]+$/$1/' #单字前2码
'fuzz/^([0-9]{3})[0-9]+$/$1/' #单字前3码
...
如果是后者,就麻烦多了

代码: 全选

'fuzz/^([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+$/$1.$2/' #二字词组各自前1码
'fuzz/^([0-9]{1})[0-9]+\.([0-9]{2})[0-9]+$/$1.$2/' #二字词组第1字第1码和第2字前2码
...
'fuzz/^([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+$/$1.$2.$3/' #三字词组各自前1码
'fuzz/^([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+\.([0-9]{2})[0-9]+$/$1.$2.$3/' #三字词组第1字第1码和第2字前1码和第3字前2码
...
'fuzz/^([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+\.([0-9]{1})[0-9]+$/$1..$3/' #三字词组第1字第1码和第3字前1码,忽略第2字
...
头像
yq-ysy
论坛版主
帖子: 4466
注册时间: 2008-07-19 12:44
来自: 广西(桂)南宁(邕)

Re: 【求助】一个 Perl“模糊查询匹配”正则表达式的写法,应该如何写?

#3

帖子 yq-ysy » 2020-03-04 10:22

astolia 写了: 2020-03-04 0:35 不知道它这个algebra是针对已经被分割了的单字编码,还是针对整个词组编码
如果是前者,取前两码应该就是...
谢谢 astolia 的指导,但我无论怎么试,都不生效。一开始怀疑是引号的问题,但删除了引号也没用。
有点怀疑是不是 Rime 这个拼写运算不支持数字?毕竟它设计之初仅考虑“拼音、五笔”这类字母按键编码的。
另外,在它的文档看到还有一个:

代码: 全选

 縮略/Abbreviation : 執行派生運算;派生出的拼寫將獲得「縮略」屬性,會在音節切分時與通常的拼寫做區分處理。

 格式:abbrev/<模式>/<替換式>/
 實例:算式 abbrev/^([a-z]).+$/$1/
 效果:以首字母爲多字母音節碼的縮寫。
 
 speller:
  algebra:
    - abbrev/^([a-z]).+$/$1/          # 簡拼(首字母)
    - abbrev/^([zcs]h).+$/$1/         # 簡拼(zh, ch, sh)
我改成 0-9 也没用。
前两天已经把这个问题放到 Github 的 rime/home 的 Issues 里问了,但目前也没有收到答复。
回复