09 November 2005
This post may be outdated due to it was written on 2005. The links may be broken. The code may be not working anymore. Leave comments if needed.
最近有位 Tong Sun 兄给我发邮件说 Lingua::Han::PinYin 里有些字的拼音是不对的。比如“小”,旧版本里显示出“shao”。还有类如“幸”等。

我原来的拼音对照表是从 Unicode::Unihan 那里拿来的。仔细读了读它的代码,发现它采用的是 2002 年的 Unihan.txt
比较老。于是从 Unicode.org 下载了比较新的 Unihan 版本。

因为拼音只是 Unihan 里的一部分。所以第一件事要做的就是从中获取 kMandarin 字段。Perl 的老本行,一次性代码:

#!/usr/bin/perl
use strict;

my $unihan_file = 'E:/Downloads/Unihan.txt';

my $i;

open(FH, $unihan_file) or die $!;
open(OUT, '>Mandarin.dat') or die $!;
while (<FH>) {
   chomp;
my ($u, $type, $value) = split(/\t/);
   next if ($type ne 'kMandarin');
   $u =~ s/^U\+//isg;
   print OUT "$u\t$value\n";
   $i++;
}
close(FH);
close(OUT);

print "Totally $i is recorded";

1;

这样所写就的 Mandarin.dat 第一个字段就是汉字的 Unicode 十六进制。而接下来的字段是汉字的拼音。
而这里的汉字的第一字段获取倒把我难了好久。这实在是因为俺水平不太好。

比如说“仱”字,在 Perl 中你可以使用

print "\x{4ef1}";
把它在 utf8 编码下显示出来。或者可以直接用 HTML
将它显示出来。而 Mandarin.dat 所对应的第一字段就是这个。
如果将一个汉字获取到这个东西?后来在 ChinaUnix.net 找到了答案。
use Encode;
my $hanzi = '仱';
my $hanzi = decode ("utf8",$hanzi);
print sprintf("%x",unpack ("U*",$hanzi));
接下来的事就简单了。重新写了下这模块。再做了点测试。就发现那几个拼音错误的都修正了。
最后增加了多个字处理和音标。Enjoy!
Download from http://fayland.org/CPAN/Lingua-Han-PinYin-0.04.tar.gz

POD

head1 NAME

Lingua::Han::PinYin - 获取汉字的拼音

head1 SYNOPSIS


use Lingua::Han::PinYin;

my $h2p = new Lingua::Han::PinYin();
print $h2p->han2pinyin("我"); # wo
my @result = $h2p->han2pinyin("爱你"); # @result = ('ai', 'ni');

# 我需要音标
my $h2p = new Lingua::Han::PinYin(tone => 1);
print $h2p->han2pinyin("我"); #wo3
my @result = $h2p->han2pinyin("爱你"); # @result = ('ai4', 'ni3');
print $h2p->han2pinyin("林道"); #lin2dao4
head1 限制

不能处理多音字。

head1 返回值

正常情况下,返回其拼音。这里总共包括了多于两万个汉字。

万一,(很可能这东西不是汉字),返回它原来的东西;

head1 选项

over 4

item tone => 1|0

默认为 0,需要音标的话设置为 1。

back

Update

修正了一个问题。并且增加了处理中英文混合字。Thank Tong Sun. 已经传到 CPAN 上了。Enjoy!


blog comments powered by Disqus