zoukankan      html  css  js  c++  java
  • 繁简转换OpenCC,autogb 和 autob5,iconv,python的jianfan包

    OpenCC

    OpenCC 是跨平台、多语言的开放中文转换库,除了基本的简繁转换功能外,用户还可以选择对不同用词习惯和异体字的处理方式。

    OpenCC 还提供方便的网页转换界面

    OpenOffice.Org的转换功能

    OpenOffice.Org提供简繁功能,使用很方便(在工具->语言->中文简繁转换)。

    Google翻译功能

    Google翻译也可以做简繁转换,效果分析见后面。

    使用cconv转换

    cconv建立在iconv之上,增加了词语转换能力,效果分析见后面。

    Ubuntu用户可以用命令sudo apt-get install cconv安装。

    使用cconv进行简繁转换的方法为:

    cconv -f UTF8-CN -t UTF8-HK jian.txt -o fan.txt
    

    使用iconv转换

    iconv是用来转换编码的小工具。现在的iconv在执行编码从gb2312到big5的转化时,实现了简繁转换。

    使用iconv进行简繁转换的方法为:

    iconv -f gb2312 -t big5 gb_input.txt > big5_output.txt
    

    如果原来的文件是UTF-8编码的,则需要使用命令:

    iconv -f utf8 -t gb2312 jian.txt | iconv -f gb2312 -t big5 | iconv -f big5 -t utf8 > fan.txt
    

    注意一定要先转化成gb2312,再由gb2312转成big5。

    繁简转换则类似:

    iconv -f utf8 -t big5 fan.txt | iconv -f big5 -t gb2312 | iconv -f gb2312 -t utf8 > jian.txt
    

    如果有zh-autoconvert,则可以用它代替中间的iconv,如

    iconv -f utf8 -t big5 fan.txt | autogb | iconv -f gbk -t utf8 > jian.txt
    

    iconv -f utf8 -t gbk jian.txt | autob5 | iconv -f big5 -t utf8 > fan.txt
    

    不同方法比较

    Note.gif
    注意:
    由于此处涉及简繁对比,请确保在左侧语言处选择“不转换”。

    测试样例

    为了方便比较,选取下面一段话做测试:

    中华人民共和国是工人阶级领导的、以工农联盟为基础的人民民主专政的社会主义国家。
    干活 干杯  西太后   后天
    

    正确的转换结果是:

    中華人民共和國是工人階級領導的、以工農聯盟為基礎的人民民主專政的社會主義國家。
    幹活 乾杯  西太后   後天
    

    测试样例中第一句话很普通,用来检测能否完成转换的基本功能;第二行“干活”与“干杯”两个词的“干”对应的繁体字不一样,这可以检测程序是否进行了语义分析;“西太后”的“后”简繁相同,同样用于检测简繁转换的准确性。

    另外,第二句话中有空格若干,用来判断转换程序是否能保留原格式。

    测试结果

    OpenCC

    中華人民共和國是工人階級領導的、以工農聯盟爲基礎的人民民主專政的社會主義國家。
    幹活 乾杯  西太后   後天
    

    OpenOffice.Org

    中華人民共和國是工人階級領導的、以工農聯盟為基礎的人民民主專政的社會主義國家。
    干活 干杯  西太后   后天
    

    Google翻译

    中華人民共和國是工人階級領導的、以工農聯盟為基礎的人民民主專政的社會主義國家。
    幹活乾杯西太后後天
    

    iconv

    中華人民共和國是工人階級領導的、以工農聯盟為基礎的人民民主專政的社會主義國家。
    幹活 幹杯  西太後   後天
    

    cconv

    中華人民共和國是工人階級領導的、以工農聯盟為基礎的人民民主專政的社會主義國家。
    幹活 乾杯  西太后   後天
    

    不难发现,对于多解的字,OpenOffice.Org未转换,iconv按单一规则转换,而cconvOpenCC和Google翻译则能正确转换。

    但是Google翻译未能保持原格式,而OpenOffice.Org、iconvcconv则很好地保留了原格式。

    另外,iconv不能处理混合编码的文件。

    使用cconv转换20M含部分乱码的文本文件耗时仅数秒,且效果非常理想,不会像iconv一样遇到“ә”等非常规字符或乱码字符时报错停止转换。(推荐使用)

    偶然需要把一些繁体字的帮助页面转换成简体字的,网上搜索啦下,还真找到一个好用的工具:zh-autoconvert ,在zh-autoconvert [Debian 包介绍]有它的介绍,这个工具是Debian中文用户于广辉先生写的自动中文辨识转码程序包,提供两个应用程序autogb 和 autob5,在Debian下很好用apt-get install zh-autoconvert 就可以安装好。两个工具使用方法也很简单
    标准的命令行为
     autogb/autob5 [选项] <输入流 >输出流
       选项有
        -i 输入流的编码
        --input 输入流的编码

        -o 输出流的编码
        --output 输出流的编码

    这样就可以同时处理繁简体和编码问题啦。
    此外 可选的编码有 gb, big5, hz, uni, utf7 或者 utf8

    实际上一般简单使用可以采用如下的方法
      autogb < 输入流(文件)   >输出流(文件)
            把输入流中的繁体字转换成简体字

      autob5 < 输入流(文件)   >输出流(文件)
            把输入流中的简体字转换成繁体字

    不过这个转换仅仅是字的转换,对于原来繁简体字中存在的多对一的情况没有特别处理,都是选用的常用字,所以一般繁转简问题不大,简转繁可能存在生造词(别字)情况,这点要注意。

    另外找到了一个windows下的工具ConvertZ这个工具可以实现比较丰富的转换,特别还能定制一些字词的转换对应关系,也算是很方便的工具啦。

    其实说到编码转换,那就不得不说到iconv这个库了,如果已经安装了这个工具,那在命令行下直接打这个命令就行了。下面就用这个工具来实现中文系统下的常用编码转换。
    
    首先,来了解一下iconv这个命令的使用方法。命令格式如下
    
    iconv -f 编码 -t 编码 文件名
    
    -f 参数指所要转换文件的文件编码,当然必须事先知道文件的编码,不然不能正确转换。
    
    -t 参数指希望转换成的文件编码,当然应该知道所指定文件的编码能不能转换成该编码,不然转换后的结果可能一无所用。比如你将中文编码转换成西欧的某种编码的话,是没有什么意义的。
    
    文件名 就是你希望转换的文件的名称的,当然也可以包含路径了。
    
    比如将a.txt文件用GB2312(简体)转换成BIG5(繁体),命令如下:
    
    $iconv -f GB2312 -t BIG5 a.txt
    
    当然也可以使用iconv -l来查看都有哪些编码可用,命令如下:
    
    $iconv -l
    
    那么,如果不知道文件的编码怎么办?比如我的系统中有繁体字编码的文件,也有UTF-8编码的文件,又有简体字编码的文件,但是系统说使用的编码是简体的。怎样把所有文件的编码都转换成简体字,或者怎样将所有文件的编码变成繁体字编码,或者怎样将所有的文件都转换成UTF-8编码呢?下面的这段程序将告诉你去怎样实现这个功能。
    
    #!/bin/bash
    
    #文件名
    fname=$1
    #临时文件,用来保存转换的结果
    tmpfile="cc`date +%0H%0M%0S`.liu"
    #没有输入文件名
    if [ -z ${fname} ] ; then
    echo "Bad file name. ";
    exit;
    fi
    #输入的文件不存在
    if [ ! -f ${fname} ] ; then
    echo "File is not existed.FILE="${fname};
    exit;
    fi
    ################################################
    # f_code:现有文件的编码,当不太清楚现有文件的编码的时候,
    # 可以同时指定的几种可能的编码
    # t_code:希望转换成的目标编码
    ################################################
    #比如要将GB2312或者UTF-8的文件转换成BIG5(繁体)文件
    t_code="BIG5" #目标编码
    f_code="GB2312 UTF-8" #可以转换的文字编码
    
    #判断系统文字编码是否为GB2312,是的话则将BIG5或者UTF-8编码的文件转换成系统一样
    #的GB2312
    echo $LANG | grep -i GB2312> /dev/null
    if [ $? -eq 0 ] ; then
    t_code="GB2312" #目标编码
    f_code="BIG5 UTF-8" #可以转换的文字编码
    fi
    
    #判断系统文字编码是否为BIG5, 是的话则将GB2312或者UTF-8编码的文件转换成系统一样
    #的GB2312
    echo $LANG | grep -i BIG5 > /dev/null
    if [ $? -eq 0 ] ; then
    t_code="BIG5" #目标编码
    f_code="GB2312 UTF-8" #可以转换的文字编码
    fi
    #如果要把GB2312,BIG5文字编码的文件统一转换成UTF-8,则应该这样
    t_code="UTF-8" #目标编码
    f_code="GB2312 BIG5" #可以转换的文字编码
    
    #当然你也可以任意设置你需要互相转换的编码,但主意要保证编码之间可以自由转换。比如
    #你要将GB2312转换成某种西欧编码,则没有什么意义了。
    normal_msg=""
    error_msg=""
    #依次尝试从可以转换的文字编码开始对文件进行编码转换
    for code in ${f_code} ; do
    #文字编码转换
    iconv -f $code -t $t_code ${fname} > ${tmpfile}
    #转换成功,一旦转换成功则不用再尝试用其他编码来读取文件
    if [ $? -eq 0 ] ; then
    normal_msg="ICONV SUCCESSED! FILENAME=${fname} F_CODE=$code,T_CODE=$t_code"
    break
    else #转换失败
    if [ ! -z "${error_msg}" ] ; then
    error_msg="${error_msg} "
    fi
    error_msg="${error_msg}ICONV FAILED! FILENAME=${fname} F_CODE=$code,T_CODE=$t_code"
    fi
    done
    #输出转换结果消息
    #转换成功,则输出转换成功消息;所有尝试转换都失败的时候,则输出所有转换失败消息
    if [ -z "${normal_msg}" ] ; then
    echo -e ${error_msg}
    else
    cp -f ${tmpfile} $fname
    echo ${normal_msg}
    fi
    
    #删除临时文件
    if [ -f ${tmpfile} ] ; then
    rm -f ${tmpfile};
    fi
    
    在上面的程序中,实际上只是实现了一个文件的转换,如果要实现多个文件的转换的话,该怎么办了,其实很简单了,只需要遍历一下文件就行了。遍历文件的方法很多,也就不详细解说了,下面仅举一个用find命令来查找文件并对找到的文件进行编码转换。命令很简单,如下:
    
    $find . -type f -name ‘*.txt’ | xargs -l sh cc.sh
    
    其中cc.sh是上面的程序文件。该命令查找当前目录下所有的后缀为txt的文件比对其进行编码转换。
    
    在上面的程序中,为了说明方便,文件编码和转换的目标编码都是在程序里设定的,如果需要更加实用一点的话,可以把原文件的编码和转换的目标编码都作为参数来输入,这样的话,这个程序就不光是中文系统下的文件编码转换了,日文,韩文等等编码的转换也能很轻松实现了。
        首先发个牢骚吧,简繁转换的问题让我在网上搜了好久都没有好的答案,得到的回答尽是让我建个简繁体字的对照表然后自己查表。我就不信了,这都什么年代了,这么常规的功能还要自己造轮子。果然工夫不负苦心人,轮子终于让我找到了,名叫opencc,ibus-pinyin里的繁体部分使用了它,项目主页地址:
        http://code.google.com/p/opencc/
        不过opencc没有一个简单的教程挺让我抓狂,自己看它的源代码才搞清楚怎么弄,为造福各位和我一样为简繁转换苦恼了很久的童鞋,本人献上这篇文章,欢迎转载,转载请注明作者RunningOn。
        在献上教程之前,提醒下面两类童鞋可以不用看本文:
        1. 写Windows程序的人。Windows自己提供了LCMapString API可以做简繁转换,搜它就行了,网上例程也多。
        2. 用python的人。python下我使用过两个包,一个是jianfan,简单直观,但有bug,有些常用的字都不能转换,推荐度一般。另外一个是opencc的python绑定,主页在http://pypi.python.org/pypi/opencc-python/,网页下方有win和linux的安装包,而且网页里有教程。看不懂英文?我了个擦,那网页里面才几个单词......

    python的jianfan包

    Linux下用C语言如何进行简繁转换。以Ubuntu 11.10为例吧,其它发行版应该大同小异。你还需要知道一些文字编码的基础知识。
        关于编码的知识这里不打算详细介绍,但你需要知道:中文中常用的编码有gb2312, gbk, gb18030, big5, utf8和unicode。严格来讲gb18030和utf8只是unicode的编码方式,但本文中简单起见把它们认为是不同的编码,想搞清楚编码关系的自己去搜吧,资料很多。
        gb2312只含简体字,big5只含繁体字,其它几种编码都同时有简体和繁体字,gb2312可以简单认为是gbk的简体子集。一般来讲简繁转换同时包含了编码的转换,比如香港地区普遍使用big5编码,转为简体字就要先转化为gbk, gb18030, utf8编码中的一种再将繁体转化为简体。
        opencc只是一个简繁转换的库,要转换编码我们还需要一个有名的库iconv。这两库的安装方法:
        sudo apt-get install libiconv-hook-dev libopencc-dev
        libopencc-dev没有提供rpm的包,也没有提供只含库的源码,所以最方便的还是apt-get。
        iconv的教程还是有不少的,这里就不做太多介绍了。但注意不是所有编码都能自由转换的,比如如果你是想把big5直接转为gb2312是不行的。
        简繁转换的通用思路是先将编码转换为utf8,再在utf8下进行简繁转换,再将utf8转为想要的编码(如果需要)。不多说,直接上代码,该解释的都写到注释里了:
    #include <iconv.h>
    #include <opencc/opencc.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <memory.h>
    
    ///使用iconv库将字符串从编码from_charset转换到to_charset,输入是inbuf,输出是outbuf
    void m_iconv(const char *from_charset, const char * to_charset,
            const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
    {
        memset(outbuf,0,outlen);
        iconv_t cd;
        cd = iconv_open(to_charset,from_charset);
        if (cd==0) return;
        iconv(cd, (char **)&inbuf, &inlen, &outbuf, &outlen);
        iconv_close(cd);
    }
    
    ///繁体转化为简体,编码从src_charset转换为dest_charset,输入是src,输出是dest
    void cht2chs(const char* src_charset, const char * dest_charset,
        const char *src, char *dest)
    {
        char utf8[1000], tempout[1000], *raw=(char *)src;
        m_iconv(src_charset, "utf8", raw, strlen(raw), utf8, sizeof(utf8));    //先转为utf8
        opencc_t od = opencc_open(OPENCC_DEFAULT_CONFIG_TRAD_TO_SIMP);
        char * chsutf8 = opencc_convert_utf8(od, utf8, strlen(utf8));    //简繁转换
        strcpy(tempout, chsutf8);
        free(chsutf8);    //一定要free不然会内存泄漏
        opencc_close(od);
        size_t len = strlen(tempout);
        m_iconv("utf8", dest_charset, tempout, len, dest, len*2+1);    //再转到目标编码
    }
    
    ///简体转化为繁体,编码从src_charset转换为dest_charset,输入是src,输出是dest
    void chs2cht(const char* src_charset, const char * dest_charset,
        const char *src, char *dest)
    {
        char utf8[1000], tempout[1000], *raw=(char *)src;
        m_iconv(src_charset, "utf8", raw, strlen(raw), utf8, sizeof(utf8));    //先转为utf8
        opencc_t od = opencc_open(OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD);
        char * chsutf8 = opencc_convert_utf8(od, utf8, strlen(utf8));    //简繁转换
        strcpy(tempout, chsutf8);
        free(chsutf8);    //一定要free不然会内存泄漏
        opencc_close(od);
        size_t len = strlen(tempout);
        m_iconv("utf8", dest_charset, tempout, len, dest, len*2+1);    //再转到目标编码
    }
    
    int main()    //main里放测试代码
    {
        char src[] = "264372270325", dest[100];    //big5编码的繁体的"测试"
        cht2chs("big5", "utf8", src, dest);    //根据实际情况,把"utf8"改为你的locale
        printf("%s
    ", dest);    //输出"测试"
        return 0;
    }
    
    将以上代码保存到test.c,可以根据实际情况将main函数第二行的utf8改为你的locale。
    编译方法:
        gcc -o test test.c -lopencc -liconv_hook
    运行:
        ./test
        然后就可以看到输出两个简体字"测试"。
        把m_iconv, cht2chs和chs2cht这三个函数复制到你的代码里就可以直接使用了。
    
        最后再说明一下,opencc算是所有简繁转换库中做得很不错的了,能处理异体字,还能对一简对多繁和一繁对多简的情况自动处理。之前有一个简繁转换的cconv项目就做得不太好,而且它用GPL协议,对开发者限制太多。而opencc使用Apache开源协议,很宽松。opencc项目很赞,可惜作者在教程上没花什么功夫,所以很长时间都没有在网上看到谁使用它。如果opencc作者看到此文请写个官方的教程吧,或者把本文直接链过去:)
  • 相关阅读:
    大部分人都会做错的经典JS闭包面试题
    20071109 QQ群:ITIL和ITSM 聊天记录,欢迎大家加入QQ群:48132184
    模式窗口window.open造成Session丢失的解决方法
    Server.Transfer 方法如何传递复杂的参数
    小游戏测试你的情商
    VS.Net 开发 MSN一样缓慢出来的提示信息的方法
    Javascript 技巧大全
    ASP.NET 2.0,无刷新页面新境界! 【转】
    ASP.NET AJAX入门系列【转】
    asp.net2.0+ajax开发的无刷新聊天室Demo【转】
  • 原文地址:https://www.cnblogs.com/timssd/p/4677026.html
Copyright © 2011-2022 走看看