★本ブログ、来週、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というモジュールを使って呼び出す方法だ。
これを簡単に紹介する。
今日はMacを使う。
以下のページをまるまる参考にした。
ぼくは2.3.6を使った。
Mac OS X MavericksへのKakasiのインストール - Qiita
ログを見ても良く分からないので、わからないなりに--forceというオプションを試した。
マニュアルはこちら。
Text::Kakasi - search.cpan.org
kakasiはデフォルトではEUCしか受け付けないので、まず下のスクリプトをEUCで保存した。
$kakasiというオブジェクトを、オプションを渡して作る。
上ではカタカナをひらがなにする-KH、JIS X 0208漢字をひらがなにする-JHを渡している。
$kakasiオブジェクトにgetメソッドで「安西マリア」という文字列を渡すと、EUCでひらがな文字列を返すはずである。
できてるっぽい。
上のマニュアルによると、-i、-oというオプションでエンコーディングを渡せばいいようだ。
以下のようになった。
なお、-outf8を渡すと、結果文字列はUTF-8内部文字列になるので、そのまま実行するとWide characters in sayという警告が出るので、上のようにSTDOUTにbinmodeを掛ける必要がある。
実行してみる。
端末コードがUTF-8になっているので、今度はコマンドラインに直接出力した。
実行する。
安藤美姫をあんどうびきと読み間違えている。
まあ日本語の読みとしてはビキの方が普通である。
kakasiで演算子を変換するとえんざんこになったこともあった。人名と捉えたわけで、びきとは逆のケースである。
これはkakasiについてくるkakasidictというテキストファイルを編集し、mkkanwaというコマンドでバイナリーに変換する。
この件は割愛する。
しかしまあ、上のファイルのソート順に限って言うと、あんどうびきでも問題ないのである。
次の字のコードは、め(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で保存した。
$kakasiというオブジェクトを、オプションを渡して作る。
上ではカタカナをひらがなにする-KH、JIS X 0208漢字をひらがなにする-JHを渡している。
$kakasiオブジェクトにgetメソッドで「安西マリア」という文字列を渡すと、EUCでひらがな文字列を返すはずである。
[perl]$ kakasitest.pl > tested.txttested.txtを開いてみる。
できてるっぽい。
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で書いたほうが分かりやすいと思うが割愛する。
安倍なつみ
安藤美姫
安めぐみ
安西マリア
[perl]$ ./kanhira.pl < names.txt
安倍なつみ あべなつみ
安藤美姫 あんどうびき
安めぐみ やすめぐみ
安西マリア あんざいまりあ
[perl]$ ./kanhira.pl < names.txt | sort -k 2
安倍なつみ あべなつみ
安西マリア あんざいまりあ
安藤美姫 あんどうびき
安めぐみ やすめぐみ
安藤美姫をあんどうびきと読み間違えている。
まあ日本語の読みとしてはビキの方が普通である。
kakasiで演算子を変換するとえんざんこになったこともあった。人名と捉えたわけで、びきとは逆のケースである。
これはkakasiについてくるkakasidictというテキストファイルを編集し、mkkanwaというコマンドでバイナリーに変換する。
この件は割愛する。
しかしまあ、上のファイルのソート順に限って言うと、あんどうびきでも問題ないのである。