2025-08-12    2025-08-12    772 字  2 分钟

目前在编汉字大概有十几万,拥有读音的约有四万多,国标通规字(共三级)总计 8105 个。其实,我们日常使用的 gb2312 单字有 6763 个左右。

在制作词库的过程中,如果只包含了通规字集,那么当你要输入生僻字的时候就会束手无策(当然,一般情况下,一般人很少有输入生僻字的需求)。如果包含了所有字集,日常输入的时候又会列出生僻字选项(不常用),徒增候选难度。

有没有一种方式可以方便地开启和关闭大字集呢?有的,往下看~

快速使用

下载如下脚本极其依赖的数据表文件:

放在配置 根目录/lua/ 目录下,如 Rime/lua/charset_filter.luaRime/lua/data/wubi86_code_table.lua 。然后,在方案文件中引用它。

engine:
  filters:
    - lua_filter@*charset_filter
    - ……

# --- 开关 ---
# reset: ← 0 1 →
switches:
  - name: charset_filter
    reset: 0
    states: [ 通规, 扩集 ]

如此,我们就可以在选单中方便地切换大、小字集。

![[assets/Pasted image 20250812153523.png|475]]

当然,日常使用我们绑定了快捷键会更加方便。

# default.custom.yaml 中
patch:
  # --- 键位绑定 ---
  key_binder/+:
    bindings/+:
      - { when: always, accept: Control+apostrophe, toggle: charset_filter }

![[assets/Pasted image 20250812153907.png|100]] ![[assets/Pasted image 20250812153920.png|100]]

这样,我们就可以通过 Ctrl+' 快捷切换字集了。

实现原理

我们通过 Rime 提供的 api 获取到开关状态,进而对候选进行过滤。对于非汉字类字符,按其原有逻辑处理,不进行任何操作。对于汉字候选项,通过遍历判断其是否在通规字字集范围中,决定是否显示。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
-- ……
        -- 通规字集
        for cand in t_input:iter() do
            local cand_text = cand.text

            -- 对于非汉字字符,直接放行
            if not is_general_char(cand_text) then
                yield(cand)
            end

            -- 遍历候选项,移除包含扩集的字词
            for i, c in utf8.codes(cand_text) do
                -- logger.info(i .. " ➭ " .. c .. " ➭ " .. utf8.char(c))
                -- 这里需要注意 utf8.char(c) 而不是 c
                if general_chars_table[utf8.char(c)] then
                    yield(cand)
                end
            end
        end
-- ……

原理及核心逻辑如上,很简单。

需要注意的是,lua 对于汉字的支持相对于其他编程语言来说显得很另类,比如对于汉字字符串的遍历需要使用 utf8.codes 方法,最最扯的一点是遍历出来的子项也需要使用 utf8.char 方法包裹起来。

当然,lua 对于中文的问题,包括但不限于上述问题(吐槽!!!)。

结语

日常使用过程中,个人是很少有输入生僻字的场景,所以这个功能的产生纯属是“可以不用,不能没有”的心态作祟,属于典型的“伪需求”。