三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

输入法词库转换从原理到实战:一文吃透深蓝词库转换的插件架构与命令行玩法

输入法词库转换从原理到实战:一文吃透深蓝词库转换的插件架构与命令行玩法

输入法词库转换从原理到实战:一文吃透深蓝词库转换的插件架构与命令行玩法

【免费下载链接】imewlconverter”深蓝词库转换“ 一款开源免费的输入法词库转换程序项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter

"换了个输入法,用了三年的词库就这么废了?"——这是几乎所有深度输入法用户都撞过的墙。搜狗细胞词库是.scel二进制,QQ 拼音自造词是.qpyd,Rime 要 YAML,微软拼音要.dat,五笔用户还有自己的码表。格式之间没有官方桥梁,词库就成了输入法生态里的"数据孤岛"。

深蓝词库转换(IME WL Converter)就是冲着这个痛点来的:一款开源免费的输入法词库转换程序,用一套统一词条模型打通 20+ 种输入法、50+ 种格式适配器,支持 Windows / Linux / macOS 三端。本文不满足于教你怎么点按钮,而是从插件架构、转换流水线、二进制逆向三个层面拆解它"凭什么能做到",再给你三套可直接复制的实战命令。

🧩 一眼看全景:一句话定位与核心能力清单

先建立全局认知。深蓝词库转换的本质是一个格式翻译引擎:把任意输入法词库读成统一内存模型,再按目标格式的规则写出去,中间可以插入过滤、简繁转换、词频重排、编码重生成等加工步骤。

核心能力清单:

  • 格式互通:搜狗、QQ、百度、谷歌、微软、Rime、拼音加加、紫光、Libpinyin、Fit 等 20+ 输入法的导入导出,其中搜狗scel、QQqpyd/qcel、百度bdict、灵格斯ld2等是逆向还原的二进制格式;
  • 编码重生成:不只是搬运,还能把纯词条"翻译"成拼音、五笔 86/98/新世纪、郑码、仓颉、注音、各种二笔(超强、轻松、现代、颖形)等编码;
  • 词库清洗流水线:长度过滤、词频过滤、去英文/数字/空格/标点、简繁互转、多音字注音,全部支持命令行组合;
  • 三端一致:WinForms 图形界面、macOS Avalonia 图形界面与 CLI 共享同一套核心引擎(src/ImeWlConverter.Core/);
  • AI 词频增强:内置 LLM 词频生成器,能对没有词频信息的词条用大模型打分量。

一次搞懂最常用的格式代码,看这张速查表(--list-formats可输出全量清单):

输入法格式代码典型文件导入导出
搜狗拼音scel/sgpy/sgpybin.scel .txt .bin
QQ 拼音qqpy/qpyd/qcel.txt .qpyd .qcel
Rime 中州韵rime.yaml .dict.yaml
微软拼音mspy.dat .txt
谷歌拼音ggpy.txt
百度拼音bdpy.txt
自定格式self任意文本

🔬 机制拆解一:为什么 50+ 种格式能"无损互转"

答案藏在项目最不起眼的三层目录结构里:Abstractions(契约层)、Core(引擎层)、Formats(适配器层)。它把"格式差异"和"核心逻辑"彻底解耦,新增一种格式只需要在src/ImeWlConverter.Formats/下写一个类,核心引擎一行都不用改。

统一词条模型是一切互转的前提。所有格式解析完都收敛成同一个数据结构——WordEntry,包含词面(Word)、词频(Rank)、编码类型与编码分段(Code)。搜狗里的"细胞词"、QQ 里的"分类词库"、Rime 里的"词典条目",落到内存里全是一个样,互转自然变成"读进来→加工→写出去"。

以文本类格式为例,所有文本导入器都继承同一个基类TextFormatImporter(源码见src/ImeWlConverter.Formats/Shared/TextFormatImporter.cs),它统一处理了读取、编码、逐行解析和错误收集,子类只需要实现三件事:

public abstract class TextFormatImporter : IFormatImporter { // 1. 本格式的编码 protected abstract Encoding FileEncoding { get; } // 2. 格式元数据(格式代码、名称、排序权重) public abstract FormatMetadata Metadata { get; } // 3. 单行如何解析成词条 —— 每种格式唯一的差异点 protected abstract IEnumerable<WordEntry> ParseLine(string line); }

这意味着,Rime 导入器只关心怎么把词\t码\t频拆开,谷歌拼音导入器只关心怎么处理词'拼音结构,至于"解析到一半某行出错怎么办""大文件要不要流式读"这类通用问题,基类已经替你兜底。这就是插件架构的威力:差异最小化,公共逻辑最大化。

⚙️ 机制拆解二:一条七段式流水线,看懂转换的全过程

深蓝词库转换的核心是ConversionPipelinesrc/ImeWlConverter.Core/Pipeline/ConversionPipeline.cs),它把一次转换编排成一条固定流水线:

导入 → 过滤 → 简繁转换 → 词频生成 → 编码生成 → 剔除无编码词条 → 导出

每个环节都是可插拔的:没配置过滤器就跳过;没配置简繁转换就原样保留;词频生成器默认走内置词频表,也可以换成 LLM。看关键片段:

// Phase 2: 过滤 —— 按配置构建过滤器管道 var filterPipeline = BuildFilterPipeline(request.FilterConfig); IReadOnlyList<WordEntry> entries = filterPipeline is not null ? filterPipeline.Apply(allEntries) : allEntries; // Phase 4: 词频生成 —— 可替换为 LLM 实现 if (_wordRankGenerator is not null) entries = await _wordRankGenerator.GenerateRanksAsync(entries, ct); // Phase 5: 编码生成 —— 拼音/五笔/郑码等走 CodeGenerationService entries = ApplyCodeGeneration(entries, request.Options.CodeGeneration, progress); // Phase 6: 剔除生成不出编码的词条(避免导出空码脏数据) if (request.Options.CodeGeneration.TargetCodeType != CodeType.NoCode) entries = entries.Where(e => e.Code is not null && e.Code.Segments.Count > 0).ToList();

过滤器管道本身也分三类(FilterPipeline.cs):单条过滤器决定词条去留(如EnglishFilter丢掉含英文的词)、变换器就地改写词条(如把空格换成下划线)、批处理过滤器面向全集合(如按词频百分比截断)。执行顺序是固定的"过滤→变换→批处理",保证组合任何过滤器都不会出现顺序歧义。

再往深一层,多音字注音是编码生成里最见功力的地方。PinyinCodeGeneratorsrc/ImeWlConverter.Core/CodeGeneration/Generators/PinyinCodeGenerator.cs)内置了WordPinyin.txt词组注音表,采用贪婪匹配 + 最长优先策略:先把表里能命中的词组按长度降序排列,逐个在词条里查找并打上"已标注"标记,避免同一个字被重复标注,剩下的单字再查单字注音表兜底:

var sortedKeys = mutiPinYinWord!.Keys.OrderByDescending(k => k.Length).ToList(); foreach (var key in sortedKeys) { var index = 0; while ((index = word.IndexOf(key, index, StringComparison.Ordinal)) != -1) { var canMatch = true; for (var i = 0; i < key.Length; i++) { if (matched[index + i]) { canMatch = false; break; } // 已被更长词组占用 } if (canMatch) { var pinyinValues = mutiPinYinWord[key]; for (var i = 0; i < pinyinValues.Count; i++) { pinyin[index + i] = pinyinValues[i]; matched[index + i] = true; } } index++; } }

"重"字单独查表是zhong,但"重要"整词命中词组表后就是zhong'yao——这正是多音字词库转换质量远超"逐字查表"的原因。

🕵️ 机制拆解三:二进制词库是怎么被"逆向"出来的

搜狗.scel、百度.bdict这类格式没有公开文档,深蓝词库转换靠的是解析二进制结构。以SougouScelImportersrc/ImeWlConverter.Formats/SougouScel/)为例:文件头部固定偏移处存着词条总数和拼音表长度,先读出拼音索引表,再按索引还原每个词的拼音,最后逐条读出词面:

// 词条总数(同音词合并计数) fs.Position = 0x120; var dictLen = ReadInt32(fs); // 拼音表长度,随后循环读索引与字符串 fs.Position = 0x1540; var pyDicLen = ReadInt32(fs); for (var i = 0; i < pyDicLen; i++) { var idx = ReadInt16(fs); var size = ReadInt16(fs); var str = new byte[size]; fs.ReadExactly(str, 0, size); var py = Encoding.Unicode.GetString(str); _pyDic.Add(idx, py); }

每个词条块内的字段布局(拼音数、词面长度、词面 Unicode 字节、扩展字段、词频)都被逐字节摸清并跳过冗余区。为了让这种逆向有据可依,项目在src/ImeWlConverterCoreTest/Test/里放了真实的.scel.qpyd.qcel.bdict.ld2样本文件,转换正确性直接和真实文件对标——这是二进制解析最可靠的保障方式。

🎯 实战演练:三套场景,覆盖个人、团队与硬核玩家

场景一:个人换机,搜狗词库一键迁到 Rime

从搜狗换成 Rime 是 Linux/开源用户最常见的迁移路径。Rime 要求词条按词频降序排列,导出器(RimeExporter)已自动完成排序,你只需要一行命令:

dotnet src/ImeWlConverterCmd/bin/Release/net10.0/ImeWlConverterCmd.dll \ -i scel -o rime -O luna_pinyin.custom.yaml 专业词库.scel

生成的文件是标准的词\t编码\t词频三列结构,直接丢进 Rime 的luna_pinyin.custom.yaml挂载即可。

场景二:团队标准化,多个来源合并清洗成统一词库

团队要统一输入法环境时,往往有多个来源的词库:市场下载的、老员工导出的、网上爬的。用--merge语义(多文件自动合并导入)加上过滤链,一次搞定"合并 + 清洗":

dotnet ImeWlConverterCmd.dll \ -i scel -o ggpy -O team_dict.txt \ -f "len:2-6|rm:eng|rm:num|rm:space" \ 技术词库.scel 市场词库.scel 老员工备份.scel

-f参数即--filter,管道符分隔多个条件:len:2-6只保留 2~6 字词条、rm:eng剔除含英文的词条、rm:num剔除含数字的、rm:space剔除含空格的。多文件场景下,任何一个文件解析失败不会中断整体任务,错误会汇总进最终报告,单文件失败不影响其余文件转换完成。

场景三:硬核玩家,自造码表与自定义输出格式

五笔/郑码/自定编码用户最大的痛点,是各家码表格式不统一。深蓝词库转换支持--code-type指定编码方案,配合--code-file挂自己的映射表、--multi-code定义多字词取码规则:

# 用自定编码表,把 scel 转成"词+编码+词频"的自定义文本 dotnet ImeWlConverterCmd.dll \ -i scel -o self -O my_dict.txt \ -c array30.txt \ -m "code_e2=p11+p12+p21+p22,code_e3=p11+p21+p31+p32" \ -F "213 ,nyyy" \ 词库.scel

-F "213 ,nyyy"的语义是:先排词、再排编码、最后排词频,词与编码间用空格分隔,字段间用逗号分隔——掌握了self格式,你几乎可以把任何词库转成任何文本排版。

🛠️ 进阶技巧与避坑指南:老手的四个经验

1. 老参数格式已成历史,别再用冒号写法。早期版本用-i:scel -o:ggpy这种带冒号写法,新版已迁移到 GNU 风格(-i scel -o ggpy)。如果你不小心用了旧格式,程序会直接报错并提示你新旧参数对照表,不会静默失效。升级脚本时记得全局替换。

2. 输出路径以/结尾就是目录模式。-O ./out/会把每个输入文件单独转成一个.txt输出到该目录;-O result.txt则把多个输入合并写进单文件。想批量转目录下的所有 scel,配合 shell 通配符即可:

for f in *.scel; do dotnet ImeWlConverterCmd.dll -i scel -o rime -O "rime_${f%.scel}.yaml" "$f" done

3. 词频为 0 的词条导出时会很尴尬。很多自造词导入后没有词频信息,导出的 Rime/搜狗文件里词频全是 0,排序会乱。解法是启用词频生成:配置 LLM(src/ImeWlConverter.Core/WordRank/LlmWordRankGenerator.cs,支持自定义ApiEndpoint / ApiKey / Model),它按每批 50 个词条调一次接口,让大模型返回 JSON 词频评分,未配置 API Key 时自动跳过、不阻塞转换。

4. 多音字转换结果异常时,先怀疑词组注音表。如果"重量"被注成zhong'liang,通常不是算法问题,而是词不在WordPinyin.txt词组表里、走了单字默认读音。想要精确结果,可以自行维护词组注音表后重新编译,或先用-f "len:..."做针对性过滤减少误伤。

📊 质量与性能:靠什么保证"转出来是对的"

词库转换工具最怕"转完才发现数据是坏的"。项目用三层测试把这件事钉死:

  • 单元测试层src/ImeWlConverterCoreTest/):覆盖编码生成器(拼音、五笔、郑码、注音、二笔、自定编码)、过滤器全组合、简繁转换、二进制解析(.scel/.qpyd/.qcel/.bdict/.ld2均有真实样本);
  • 集成测试层tests/integration/):按"导入→导出→高级功能→回归"四组用例组织,每组都配有expected/期望输出文件做逐字节比对,回归用例专门盯住 wb86/wb98/jidian/wbnewage 等高频格式不退化;
  • CI 链路Makefilemake test跑单元测试、make integration-test跑端到端比对、make lint校验代码格式,Release 发布还叠加了PublishTrimmed单文件裁剪。

一个值得注意的工程细节:集成测试的期望文件不是手写的,而是通过regenerate-expected-exports.sh脚本用当前版本"回灌"生成,再靠 git 审查 diff 来确认变更是否符合预期——这保证了期望文件永远和真实输出结构同步,不会出现"测试过了但格式早变了"的假绿。

性能上,文本导入器提供了ImportStreamingAsync流式逐行解析接口,配合管道里的CancellationToken取消机制,超大词库(几十万词条)也能边读边转、随时中断,不会一次性把整个文件塞进内存。

🚀 上手路径:从零到第一次转换,五步走完

前置条件只有一条:安装 .NET SDK 10.0 或更高版本(dotnet --version验证)。

# 1. 克隆仓库 git clone https://gitcode.com/gh_mirrors/im/imewlconverter cd imewlconverter # 2. 构建命令行工具(或用 make build-cmd) dotnet build src/ImeWlConverterCmd # 3. 查看完整帮助与所有格式代码 dotnet src/ImeWlConverterCmd/bin/Release/net10.0/ImeWlConverterCmd.dll --help dotnet src/ImeWlConverterCmd/bin/Release/net10.0/ImeWlConverterCmd.dll --list-formats # 4. 跑你的第一个转换:scel → 谷歌拼音 dotnet src/ImeWlConverterCmd/bin/Release/net10.0/ImeWlConverterCmd.dll \ -i scel -o ggpy -O output.txt 我的词库.scel # 5. 进阶:加过滤器 + 指定拼音编码 dotnet src/ImeWlConverterCmd/bin/Release/net10.0/ImeWlConverterCmd.dll \ -i scel -o qqpy -O clean.txt -f "len:2-8|rank:>50" -t pinyin 我的词库.scel

想用图形界面?Windows 用 WinForms 版,macOS 用 Avalonia 版(src/ImeWlConverterMac/),两者的转换引擎与 CLI 完全共享,界面上所有选项都能在命令行找到对应参数。

🔮 生态与展望:这个项目还在往哪走

docs/下的MIGRATION.md(命令行迁移指南)、docker.md(Docker 化部署)到openspec/里的规格文档(LLM 词频配置、命令行参数解析重构、scel 导出等提案),这个项目保持着相当规范的工程化演进节奏。已经落地的方向包括:GNU 风格参数体系的重构、LLM 词频生成的接入、scel 导出能力的补齐、macOS 原生应用的发布流水线(make package-all一键产出多平台安装包)。

对于输入法重度用户而言,深蓝词库转换解决的不是"这一次迁移",而是一劳永逸的数据主权问题:只要词库能自由进出各家格式,你就永远有"用脚投票"换输入法的自由。这也是它十多年来持续维护的核心价值——把词库还给你,把选择权也还给你。

现在,打开终端,克隆项目,用上面的命令把你的第一份词库迁出去。换输入法这件事,从今天起不再是"搬家",而是一次普通的数据同步。

【免费下载链接】imewlconverter”深蓝词库转换“ 一款开源免费的输入法词库转换程序项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表