旧かなから新かな候補一覧を列挙する Perl ワンライナー

ちょっと必要になったので書きました。

perl -CSD -Mutf8 -F/\\t/ -nle 'sub apply_rule{ my ($before, $func, @arr)=@_; my @result=(); for my $str(@arr) { my @temp=(""); my $pos=0; while ($str=~/($before)/g) { my $old_pos=$pos; $pos=pos($str); my @temp2=map{my $s=substr($str, $old_pos, $pos-$old_pos-length($1)); $_.$s.$1, $_.$s.(&$func($1));} @temp; @temp=@temp2; } push @result, map{$_.substr($str, $pos)} @temp; } @result; } sub to_new_kana{ my $str; ($str=shift)=~tr/ゐゑ/いえ/; @result=apply_rule(qr{(?:[ぢづ]|(?<=.)[はひふへほ]|(?<=[^っ])つ|(?<=[きしちにひみりぎじぢびぴ])[やゆよ]|く(?=[かきくけこ]))}, sub{my $t; ($t=shift)=~tr/ぢづはひふへほつくやゆよ/じずわいうえおっっゃゅょ/; $t}, $str); @result=apply_rule(qr{[あかさたなはまやらわゃがざだばぱ](?=う)}, sub{my $t; ($t=shift)=~tr/あかさたなはまやらわゃがざだばぱ/おこそとのほもよろおょごぞどぼぽ/; $t; }, @result); @result=apply_rule(qr{[いきしちにひみりぎじぢびぴ](?=う)}, sub{my $t; $t=shift; $t eq "い" ? "ゆ" : $t."ゅ"}, @result); @result=apply_rule(qr{[えけせてねへめれげぜでべぺ](?=う)}, sub{my $t; $t=shift; return "よ" if $t eq "え"; $t=~tr/けせてねへめれげぜでべぺ/きしちにひみりぎじじびぴ/; $t."ょ"; }, @result); @result=apply_rule(qr{[くぐ][ゎわ]}, sub{my $t; ($t=shift)=~tr/くぐ/かが/; $t=~s/[ゎわ]$//; $t; }, @result);  } print join(",", to_new_kana($_)); '

標準入力から旧かなを受け取り、標準出力に対応する新かな候補をカンマ区切りで列挙します。

旧かなを正しく新かなにしようと思うと形態素解析が必要なのですが、かなしかない場合はいろいろな候補ができます。例えば、「けふはくじやう」という入力に対しては、「けふはくじやう,けふはくじよう,けふはくじゃう,けふはくじょう,けふわくじやう,けふわくじよう,けふわくじゃう,けふわくじょう,けうはくじやう,きょうはくじやう,けうはくじよう,きょうはくじよう,けうはくじゃう,きょうはくじゃう,けうはくじょう,きょうはくじょう,けうわくじやう,きょうわくじやう,けうわくじよう,きょうわくじよう,けうわくじゃう,きょうわくじゃう,けうわくじょう,きょうわくじょう」という新かな候補ができます。

どういう時に使うかというと、例えば漢字とかなのペアを入手した時、すでに新かなで持っているものをフィルタリングしたいというような場合です。例えば、「脅迫状:けふはくじやう」というペアがあって、すでに持っている辞書に「脅迫状:きょうはくじょう」というエントリがあれば、「けふはくじやう」から上記の候補を列挙して、その中に「きょうはくじょう」があることから、これはすでに新かなで持っている読みだということがわかります。