雖然在 Perl 中可以 use Encode::HanConvert 來轉換。但還是同樣的問題,若要打包成執行檔會包出一大包怪物。在速度效能上的考量,Sean 還是使用 Windows API 來轉換。
在 GBK 字集中包含所有簡體與繁體字,所以 Sean 的程式都先轉成 GBK 再呼叫系統的 LCMapString。
這個函不該稱「簡繁轉碼」,應該稱「簡繁轉『字』」。因為編碼並沒有改變。函式傳入的字串使用 Unicode (Perl預設UTF8),回傳值也是 Unicode 字串,僅做簡繁字互轉。
Sean 已寫成 Perl 模組,完整的程式在這裡。
題外話,簡繁體字並非一對一的關係唷,因為無法100%逆轉。
例如繁體「干」「幹」「乾」簡體皆為「干」,再轉回繁體還是「干」。
use Encode qw(encode decode);
use Win32::API;
use utf8;
use strict;
use constant LOCALE_SYSTEM_DEFAULT => 0x0800;
use constant LANG_CHINESE_SIMPLIFIED => 0x0804;
use constant LANG_CHINESE_TRADITIONAL => 0x0404;
use constant LCMAP_SIMPLIFIED_CHINESE => 0x02000000;
use constant LCMAP_TRADITIONAL_CHINESE => 0x04000000;
# Perl 的 Unicode 字串正體中文轉簡體中文
sub ToCHS {
my $source = ToANSI(shift,'GBK');
my $len = length($source);
my $target = "\0" x $len;
$API_LCMapString = new Win32::API('kernel32','LCMapString','NNPNPN','N') unless defined $API_LCMapString;
my $ret = $API_LCMapString->Call(LANG_CHINESE_SIMPLIFIED,LCMAP_SIMPLIFIED_CHINESE,$source,$len,$target,$len);
return undef unless $ret;
return(ToUnicode($target,'GBK'));
}
# Perl 的 Unicode 字串簡體中文轉正體中文
sub ToCHT {
my $source = ToANSI(shift,'GBK');
my $len = length($source);
my $target = "\0" x $len;
$API_LCMapString = new Win32::API('kernel32','LCMapString','NNPNPN','N') unless defined $API_LCMapString;
my $ret = $API_LCMapString->Call(LANG_CHINESE_SIMPLIFIED,LCMAP_TRADITIONAL_CHINESE,$source,$len,$target,$len);
return undef unless $ret;
return(ToUnicode($target,'GBK'));
}

0 個回應:
張貼意見