如何在Enchant中使用自定义词表?功能异常及合并问题求助
问题描述
我无法让个人词表(PWL)在Enchant中正常工作。我有一份每行一个单词的技术术语列表,之前在命令行Hunspell里用了很久,但执行以下PHP代码后,$suggestions返回空数组:
$b = enchant_broker_init(); $dict = enchant_broker_request_pwl_dict($b,'/path/to/my.pwl'); // enchant_dict_add($dict,'monospace'); // 该单词已在文件中 $suggestions = enchant_dict_suggest($dict,'monaspace');
这难道不是enchant_broker_request_pwl_dict的正确用法吗?
我的核心需求是把内置英文词典和自定义词表合并。我知道可以用enchant_dict_add_to_session在内存中添加单词,但现在想先解决当前PWL的问题。
环境:Mac + PHP 8.0,拼写后端为aspell。
更新1
发现enchant_dict_check配合PWL可以正常工作,只要文件里的单词是小写,检查不区分大小写:
enchant_dict_check($dict,'Monospace'); // 返回true enchant_dict_check($dict,'monospace'); // 返回true
但自定义单词无法生成拼写建议,这没什么实际用处。Enchant的推荐解决方案是什么?
更新2
在使用Hunspell作为后端的Linux服务器上安装了Enchant,这里enchant_broker_request_pwl_dict按上述代码可以正常工作,但enchant_dict_add_to_session失效了。除了对每个单词做两次拼写检查(先查自定义词表再查基础词典),我还是不知道怎么合并自定义词汇和基础词典。
解决方案
1. PWL无法生成拼写建议的本质原因
Enchant的PWL词表本质只是一个**“允许列表”**,仅用于放行拼写检查,不会生成拼写建议——因为PWL没有词形规则、相似词库等支撑数据,这是设计上的限制,和使用的后端(aspell/hunspell)无关。
如果需要自定义单词也能生成拼写建议,有两种可行方案:
- 合并到Hunspell词典:把PWL单词添加到Hunspell的
.dic文件中(部分词典需同步更新.aff规则文件),让Enchant直接加载修改后的完整词典; - 组合多词典实例:同时初始化基础词典和PWL词典,拼写检查时先查PWL,未命中再查基础词典;生成建议时调用基础词典的
enchant_dict_suggest,再手动补充PWL中与输入词相似的单词(可通过编辑距离等字符串相似度算法筛选)。
2. 合并自定义词表与基础词典的实现代码
不要用PWL单独替代基础词典,而是通过Enchant Broker管理多个词典实例,实现自定义检查与建议逻辑:
$broker = enchant_broker_init(); // 加载基础英文词典 $baseDict = enchant_broker_request_dict($broker, 'en_US'); // 加载自定义PWL词表 $pwlDict = enchant_broker_request_pwl_dict($broker, '/path/to/my.pwl'); // 自定义拼写检查:优先查PWL,再查基础词典 function custom_check($pwlDict, $baseDict, $word) { return enchant_dict_check($pwlDict, $word) || enchant_dict_check($baseDict, $word); } // 自定义拼写建议:基础词典结果 + PWL中相似单词 function custom_suggest($pwlDict, $baseDict, $word, $pwlPath) { $suggestions = enchant_dict_suggest($baseDict, $word); // 读取PWL并筛选相似词(编辑距离≤2视为相似) $pwlWords = file($pwlPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach ($pwlWords as $pwlWord) { if (levenshtein($word, $pwlWord) <= 2) { $suggestions[] = $pwlWord; } } // 去重后返回 return array_unique($suggestions); } // 使用示例 $word = 'monaspace'; echo custom_check($pwlDict, $baseDict, $word) ? '拼写正确' : '拼写错误'; print_r(custom_suggest($pwlDict, $baseDict, $word, '/path/to/my.pwl')); // 清理资源 enchant_broker_free_dict($baseDict); enchant_broker_free_dict($pwlDict); enchant_broker_free($broker);
3. Linux下enchant_dict_add_to_session失效的替代方案
enchant_dict_add_to_session的生效依赖后端支持,Hunspell部分版本对会话级单词添加的兼容性较差。替代方案:
- 临时将单词写入PWL文件后重新加载词典(会修改本地文件);
- 内存中维护自定义单词数组,在检查和建议逻辑中优先读取该数组,与基础词典配合使用(类似上述自定义函数逻辑)。
内容的提问来源于stack exchange,提问作者Tim

