[原创]使用OPENCC库进行简繁转换(C++代码)
最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量。
所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换)。
顾此记录一些OPENCC的库使用教程,即C++中调用OPENCC库完成字符转换。
注意:OpenCC并非类似iconv的库,他只是一个内码转换库,请勿用于类似iconv场景,请注意区分。
OpenCC的介绍:
Open Chinese Convert (OpenCC, 開放中文轉換) is an opensource project for conversion between Traditional Chinese and Simplified Chinese, supporting character-level conversion, phrase-level conversion, variant conversion and regional idioms among Mainland China, Taiwan and Hong kong.
中文簡繁轉換開源項目,支持詞彙級別的轉換、異體字轉換和地區習慣用詞轉換(中國大陸、臺灣、香港)。
Features 特點
- 嚴格區分「一簡對多繁」和「一簡對多異」。
- 完全兼容異體字,可以實現動態替換。
- 嚴格審校一簡對多繁詞條,原則爲「能分則不合」。
- 支持中國大陸、臺灣、香港異體字和地區習慣用詞轉換,如「裏」「裡」、「鼠標」「滑鼠」。
- 詞庫和函數庫完全分離,可以自由修改、導入、擴展。
- 支持C、C++、Python、PHP、Java、Ruby、Node.js and Android。
- 兼容Windows、Linux、Mac平臺。
通过以上介绍可以发现,OpenCC是一款较为完美的简繁转换字库,此处注意,OpenCC是针对简繁转换的,并不适用于其他国家字符,其他国际语言,请使用iconv。
附OpenCC测评:http://linux-wiki.cn/wiki/zh-hans/%E7%AE%80%E7%B9%81%E8%BD%AC%E6%8D%A2
附在线简繁测试:http://opencc.byvoid.com/
此处针对WINDOWS平台做开发,Linux等请参考官方文档。
1、安装以及编译OpenCC
OpenCC的下载:https://github.com/BYVoid/OpenCC
当前最新版本为: 1.0.4
下载后解压缩,安装CMAKE后在路径执行以下语句:
cmake -H. -Bbuild -G"Visual Studio 12" -DCMAKE_INSTALL_PREFIX="path/to/install" cmake --build build --config Release --target install
此处注意,VS2013以上版本不兼容XP,请注意更改SLN中的设置。
路径特别注意,写相对路径容易产生出现重复路径无法编译的情况。
此处如果只需要用到开发库 那么只需要执行
cmake -H. -Bbuild -G"Visual Studio 12" -DCMAKE_INSTALL_PREFIX="path/to/install"
然后会生成Build目录,打开下面的SLN即可。
注意OPENCC有用大量的C11特性,在低于2013版本很难编译通过,如果你使用低于2013调用DLL,那么就要注意不要使用网上发布的源码,接下来我会介绍如何转换。
接下来只需要编译OPENCC并将DLL,INCLUDE等文件发布并整合即可,这里就不单独介绍了,非常简单的。
此处1.0.4版本中项目:opencc_phrase_extract 是无法编译的,在GIT上也有对应的issue,删除该项目即可,不影响使用,所以不用管他。
2、在代码中使用OpenCC
当完成以上步骤之后,我们就可以正式在自己的代码中使用openCC进行转换繁体了。
这里特别注意一下,OpenCC只是一个基于utf8格式的简繁转换库,并不存在和iconv相同的转换,所以接下来的代码会使用到大量的boost locale,如果觉得不习惯,可以自己替换成iconv。
介绍一下配置文件的含义(以下内容摘自官方GIT):
Configurations 配置文件
預設配置文件
s2t.json
Simplified Chinese to Traditional Chinese 簡體到繁體t2s.json
Traditional Chinese to Simplified Chinese 繁體到簡體s2tw.json
Simplified Chinese to Traditional Chinese (Taiwan Standard) 簡體到臺灣正體tw2s.json
Traditional Chinese (Taiwan Standard) to Simplified Chinese 臺灣正體到簡體s2hk.json
Simplified Chinese to Traditional Chinese (Hong Kong Standard) 簡體到香港繁體(香港小學學習字詞表標準)hk2s.json
Traditional Chinese (Hong Kong Standard) to Simplified Chinese 香港繁體(香港小學學習字詞表標準)到簡體s2twp.json
Simplified Chinese to Traditional Chinese (Taiwan Standard) with Taiwanese idiom 簡體到繁體(臺灣正體標準)並轉換爲臺灣常用詞彙tw2sp.json
Traditional Chinese (Taiwan Standard) to Simplified Chinese with Mainland Chinese idiom 繁體(臺灣正體標準)到簡體並轉換爲中國大陸常用詞彙t2tw.json
Traditional Chinese (OpenCC Standard) to Taiwan Standard 繁體(OpenCC 標準)到臺灣正體t2hk.json
Traditional Chinese (OpenCC Standard) to Hong Kong Standard 繁體(OpenCC 標準)到香港繁體(香港小學學習字詞表標準)
一般情况下对于常用的简繁互转,我这里测试后推荐:s2t 或 t2s的配置文件,当涉及到聊天等内容时一般建议使用 s2tw 或 tw2s即可,剩下的未测试,建议自行测试后选择。
配置文件的内容非常简单,对应相应的OCD文件,以s2t.json为例:
{ "name": "Simplified Chinese to Traditional Chinese", "segmentation": { "type": "mmseg", "dict": { "type": "ocd", "file": "STPhrases.ocd" } }, "conversion_chain": [{ "dict": { "type": "group", "dicts": [{ "type": "ocd", "file": "STPhrases.ocd" }, { "type": "ocd", "file": "STCharacters.ocd" }] } }] }
看到内容中使用了大量ocd,但是你发现你那边没有ocd是吧,很正常因为ocd需要使用他的工具生成,生成后也不在data\dictionary目录下,而是在build\data目录下,所以找寻的时候要注意,同时如果你实在懒得弄,完全可以使用txt,ocd是为了加速读取,不需要在意它,你如果毫不在意这种速度差异,建议使用txt文件,在data\dictionary目录下查找即可,但是配置文件中的ocd文件均要修改为txt,例如:
{ "name": "Simplified Chinese to Traditional Chinese", "segmentation": { "type": "mmseg", "dict": { "type": "text", "file": "STPhrases.txt" } }, "conversion_chain": [{ "dict": { "type": "group", "dicts": [{ "type": "text", "file": "STPhrases.txt" }, { "type": "text", "file": "STCharacters.txt" }] } }] }
配置文件搞完了,我们可以开始编写自己的代码了,这里要注意的是,如果你使用低版本的例如vs2005等版本调用opencc.dll时,你会发现网上的很多教程是错的,因为会产生bad_alloc异常,具体原因还是在于不兼容吧,这里如果是用标准C+调用传参就不会出现异常(如果你有其他更好的办法,请联系我),我的解决办法是,直接调用opencc提供的C函数:
编写一个 GBK转换为BIG5的函数为例:
opencc_t gs2twhwd = NULL; if (gs2twhwd == NULL) gs2twhwd = opencc_open("s2t.json"); // step 1 转换为UTF8 std::string szConvsert = lc::to_utf<char>(szGBK,"GBK"); szConvsert = opencc_convert_utf8(gs2twhwd,szConvsert.c_str(),szConvsert.size()); // 转换文本GBK to BIG5 szConvsert = lc::from_utf(szConvsert,"BIG5"); // 转换为本地字符集
大家可以看到,我使用的是标准C函数,这样就不存在低版本VC++兼容高版本VC++的问题。
3、发布OpenCC函数
当完成以上代码编写,接下来要做的就是发布OpenCC的程序,这样就可以完美的跑起来了。
发布非常简单,例如使用s2t.json 以及 t2s.json时,发布配置文件与程序执行文件同级目录,并将ocd或txt文件放到同样目录下即可。
但是这里要注意的是,我们只需要发布我们用得到的文件即可,不需要去发布其他完全未使用的文件增大发布大小。
设置自定义目录的方法:
例如我希望把所有配置文件放到lang目录下,那么加载配置文件的时候要写
gs2twhwd = opencc_open("lang\\s2t.json");
而配置文件中,也要修改为:
{ "name": "Simplified Chinese to Traditional Chinese", "segmentation": { "type": "mmseg", "dict": { "type": "text", "file": "lang\\STPhrases.txt" } }, "conversion_chain": [{ "dict": { "type": "group", "dicts": [{ "type": "text", "file": "lang\\STPhrases.txt" }, { "type": "text", "file": "lang\\STCharacters.txt" }] } }] }
以上之后就可以将数据加载到其他位置,当然具体要你自己测试,以上均为相对路径,所以自己程序代码内要管理好对应的目录,否则比较容易出现异常。