イジハピ!

TwitterID:@query1000こと深沢千尋のブログです。
You're not like me so I like you ♡
さいきんブログの評判が意外と気になるようになってきました。
読んで気に入った人はTwitter、Facebook、コメントで反応ください!

【第648回】Text::Kakasiを使って漢字かな逆変換

★本ブログ、来週、7月28日の週はお休みします。

辞書は文字コード順に並ぶ。
英語の場合、これは問題にならない。
love、kiss、hug、embraseという言葉をソートするとembrase<hug<kiss<loveという順に並ぶ。

しかし日本語はちょっと困る。
安倍なつみ
安藤美姫
安めぐみ
安西マリア
という人名が以下のように並ぶ。
[blog]$ cat names.txt
安倍なつみ
安藤美姫
安めぐみ
安西マリア
[blog]$ sort names.txt   # 文字コードでソート
安めぐみ
安倍なつみ
安藤美姫
安西マリア
まず最初の安という字は全部同じ字であるから、ソートに使われない。
次の字のコードは、め(U+3081)<倍(U+5001)<富(U+5BCC)<西(U+897F)というUnicode順になっている。

名簿としては、日本語の読み順で、あべなつみ<あんざいまりあ<あんどうみき<やすめぐみという順に並んで欲しい。
ここで必要なのがふりがなである。

漢字からふりがなを生成するのが漢字かな逆変換だ。
いくつか方法があると思うが、よく使っていたのはkakasiというプログラムをPerlからText::Kakasiというモジュールを使って呼び出す方法だ。
これを簡単に紹介する。

kakasiをインストール

まずインストールする。
今日はMacを使う。

以下のページをまるまる参考にした。
ぼくは2.3.6を使った。

Mac OS X MavericksへのKakasiのインストール - Qiita
[kakasi]$ tar xvf kakasi-2.3.6.tar.gz
[kakasi]$ cd kakasi-2.3.6/
[kakasi-2.3.6]$ ./configure -host=powerpc-apple-bsd
[kakasi-2.3.6]$ make
[kakasi-2.3.6]$ sudo make install
[kakasi-2.3.6]$ brew install nkf
[kakasi-2.3.6]$ echo "あいうえお" | nkf -e | kakasi -Ha
aiueo

Text::Kakasiをインストール

次にcpanmでText::Kakasiをインストールしたが、ここで問題が起こった。
[kakasi-2.3.6]$ sudo cpanm --force Text::Kakasi
Password:
--> Working on Text::Kakasi
Fetching http://www.cpan.org/authors/id/D/DA/DANKOGAI/Text-Kakasi-2.04.tar.gz ... OK
Configuring Text-Kakasi-2.04 ... OK
Building and testing Text-Kakasi-2.04 ... FAIL
! Installing Text::Kakasi failed. See /Users/query1000/.cpanm/work/1406105230.16479/build.log for details. Retry with --force to force install it.
エラーが起きているという。
ログを見ても良く分からないので、わからないなりに--forceというオプションを試した。
[kakasi-2.3.6]$ sudo cpanm --force Text::Kakasi
--> Working on Text::Kakasi
Fetching http://www.cpan.org/authors/id/D/DA/DANKOGAI/Text-Kakasi-2.04.tar.gz ... OK
Configuring Text-Kakasi-2.04 ... OK
Building and testing Text-Kakasi-2.04 ... FAIL
! Testing Text-Kakasi-2.04 failed but installing it anyway.
Successfully installed Text-Kakasi-2.04
1 distribution installed
エラーは相変わらず出てるけど、インストールはしたよと言われた。

プログラムを書く

最初にへなちょこなプログラムを書く。
マニュアルはこちら。

Text::Kakasi - search.cpan.org

kakasiはデフォルトではEUCしか受け付けないので、まず下のスクリプトをEUCで保存した。
03
$kakasiというオブジェクトを、オプションを渡して作る。
上ではカタカナをひらがなにする-KH、JIS X 0208漢字をひらがなにする-JHを渡している。

$kakasiオブジェクトにgetメソッドで「安西マリア」という文字列を渡すと、EUCでひらがな文字列を返すはずである。
[perl]$ kakasitest.pl > tested.txt
tested.txtを開いてみる。
51
できてるっぽい。

UTF-8化する

でもUTF-8を使いたい。
上のマニュアルによると、-i、-oというオプションでエンコーディングを渡せばいいようだ。
以下のようになった。
#! /usr/local/bin/perl
#
# kakasitest.pl -- Text::Kakasiのテスト

use 5.010;
use strict;
use warnings;
use Text::Kakasi;
binmode STDOUT, ":encoding(UTF-8)";

my $kakasi = Text::Kakasi->new(qw/-iutf8 -outf8 -KH -JH/);
say $kakasi->get('安西マリア');

なお、-outf8を渡すと、結果文字列はUTF-8内部文字列になるので、そのまま実行するとWide characters in sayという警告が出るので、上のようにSTDOUTにbinmodeを掛ける必要がある。

実行してみる。
端末コードがUTF-8になっているので、今度はコマンドラインに直接出力した。
[perl]$ ./kakasitest.pl
あんざいまりあ
出来たね。

フィルター化する

ということで、標準入力から入力を受け取って、タブ区切りでふりがなを振って表示するプログラムにしてみる。
#! /usr/local/bin/perl
#
# kanhira.pl -- よみがなをふるツール

use 5.010;
use strict;
use warnings;
use Text::Kakasi;

binmode STDIN, ":encoding(UTF-8)";
binmode STDOUT, ":encoding(UTF-8)";

my $kakasi = Text::Kakasi->new(qw/-iutf8 -outf8 -KH -JH/);

while (<STDIN>) {
   chomp;
   say $_, "\t", $kakasi->get($_);
}

実行する。
[perl]$ cat names.txt
安倍なつみ
安藤美姫
安めぐみ
安西マリア
[perl]$ ./kanhira.pl < names.txt
安倍なつみ あべなつみ
安藤美姫 あんどうびき
安めぐみ やすめぐみ
安西マリア あんざいまりあ
[perl]$ ./kanhira.pl < names.txt | sort -k 2
安倍なつみ あべなつみ
安西マリア あんざいまりあ
安藤美姫 あんどうびき
安めぐみ やすめぐみ
実際にはソート機能までPerlで書いたほうが分かりやすいと思うが割愛する。

安藤美姫をあんどうびきと読み間違えている。
まあ日本語の読みとしてはビキの方が普通である。
kakasiで演算子を変換するとえんざんこになったこともあった。人名と捉えたわけで、びきとは逆のケースである。

これはkakasiについてくるkakasidictというテキストファイルを編集し、mkkanwaというコマンドでバイナリーに変換する。
この件は割愛する。

しかしまあ、上のファイルのソート順に限って言うと、あんどうびきでも問題ないのである。
プロフィール

query1000

THE BOOKS
New!













最新コメント
<%==comments[n].author%>
<% } %>
sponsored link
<% for ( var i = 0; i < 7; i++ ) { %> <% } %>
<%= wdays[i] %>
<% for ( var i = 0; i < cal.length; i++ ) { %> <% for ( var j = 0; j < cal[i].length; j++) { %> <% } %> <% } %>
0) { %> id="calendar-964509-day-<%= cal[i][j]%>"<% } %>><%= cal[i][j] %>
月別アーカイブ
最新記事
カテゴリ別アーカイブ
記事検索
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

'); label.html('\ ライブドアブログでは広告のパーソナライズや効果測定のためクッキー(cookie)を使用しています。
\ このバナーを閉じるか閲覧を継続することでクッキーの使用を承認いただいたものとさせていただきます。
\ また、お客様は当社パートナー企業における所定の手続きにより、クッキーの使用を管理することもできます。
\ 詳細はライブドア利用規約をご確認ください。\ '); banner.append(label); var closeButton = $('