だるろぐ

だるいぶろぐです

perlとkakasiを使って漢字の読み仮名を得る

あるところに読み仮名の無い文字列 なデータがn件ありました。


俺  「読み仮名を入力するだけの簡単なお仕事が始まるお」
ボス 「それkakasiで」


そういえばそんな便利なものがありました。どうでもいいけどkakasiとかnamazuとか、変わった名前が多いよね。
というわけで書いた。

前準備:kakasiインストール

% wget http://kakasi.namazu.org/stable/kakasi-2.3.4.tar.gz
% tar zxf kakasi-2.3.4.tar.gz
% cd kakasi-2.3.4
% ./configure; make; sudo make install
% sudo cpanm Text::Kakasi

コード

use strict;
use warnings;
use Encode qw/find_encoding/;
use Text::Kakasi;
use Test::More;

my $hiragana = qr/\p{InHiragana}/;
my $katakana = qr/\p{InKatakana}/;
my $kanji    = qr/\p{InCJKUnifiedIdeographs}/;
my $suuji    = qr/\p{InHalfwidthAndFullwidthForms}/;#数字だけじゃないけど

my $k = Text::Kakasi->new(qw/-iutf8 -outf8 -JH -f/);
my $u = find_encoding('utf8');

sub en {$u->encode(shift)}
sub de {$u->decode(shift)}

sub parse {
    my $kana = shift;
    $kana = $k->get($kana);
    $kana =~ s/(?:\].*?\[)//g;
    $kana =~ s/^.*?\[//;
    $kana =~ s/\]$//;
    $kana;
}

sub yomi {
    my $in = shift;
    my @r = split /($hiragana+)|($katakana+)|($kanji+)|($suuji+)/, $in;
    my $out;
    for my $part (grep {$_} @r) {
        $out .= $part =~ m/^$kanji+$/ ? parse($part) : $part;
    }
    $out;
}

{
    use utf8;

    my @data = (qw/
        ほげ ほげ
        富士山 ふじさん
        東京 とうきょう
        マウス マウス
        紙コップ かみコップ
        バニラ味 バニラあじ
        地上4階 ちじょう4かい
        長万部 おしゃまんべ
        屈斜路湖 くっしゃろこ
        日暮里 にっぽり
    /);

    for (grep {not ($_ % 2)} (0 .. $#data)) {
        is (yomi($data[$_]), $data[$_ + 1], en("$data[$_]\t-> $data[$_ + 1]"));
    }
}

done_testing;

実行

% perl kakasi.pl
ok 1 - ほげ     -> ほげ
ok 2 - 富士山   -> ふじさん
ok 3 - 東京     -> とうきょう
ok 4 - マウス   -> マウス
ok 5 - 紙コップ -> かみコップ
ok 6 - バニラ味 -> バニラあじ
ok 7 - 地上4階 -> ちじょう4かい
ok 8 - 長万部   -> おしゃまんべ
ok 9 - 屈斜路湖 -> くっしゃろこ
ok 10 - 日暮里  -> にっぽり
1..10


あら便利。
カタカナとか数字とかも平仮名にしたければ Lingua::JA::Regular::Unicode とか使えばいいと思います。