Perlで(UTF-8)文字列を扱う基礎中の基礎

ちょっと前に記事を書いたつもりになっていて全く書いていなかったのでメモ。
これをおさえておけば、特殊なケース以外はたいていうまくいくと思います。

一番初めに

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Encode;

と書きます。日本語を扱う可能性があるプログラムのすべて(つまり、あなたが文字列処理をするプログラムの全て)に、書いておくと幸せになれるらしいですよ。

Perl内部のUTF-8UTF-8

文字列がUTF-8ならUTF-8じゃないか?と思われるかもしれません。が、しかしPerlには「内部で扱うflagged UTF-8」と「flaggedではない外部のUTF-8」の二種類があることを覚えておきましょう。
文字列を扱う時は、Perl内部で扱うflagged UTF-8へdecodeで変換し、Perlの外部に出力する時にはencodeしてやる必要があります。例えば、ターミナルから入力されるひらがなをカタカナに変換する場合は、次のようになります。

#!/usr/bin/perl 

use strict;
use warnings;
use utf8;
use Encode;

my $hoge = <>;

my $decoded_hoge = decode_utf8($hoge);

$decoded_hoge =~ tr/ぁ-ん/ァ-ン/;

print encode_utf8($decoded_hoge);

これでたいていの処理は問題なくできるはずです。

以下余談

dankogaiさんのサイトですが、binmode()には気をつけましょう。とりわけスレッドを使ったプログラムを書く場合、書き方によってはsegmentation faultを起こします( 参考 : use threads; するときに注意すべきこと の続編 - punitan (a.k.a. punytan) のメモ )
binmode()とencoding()は使わずに、find_encoding()を使うことでこの問題を回避できるので、なにかとりわけ指定したエンコードで出力したい場合は、常にfind_encoding()を使うようにしましょう。binmodeは楽にかけそうで良いんですが、ここがネックとなります。

  • もっと知りたくなったら

http://d.hatena.ne.jp/tokuhirom/20080408/1207619640
あたりを読むと良いのではないでしょうか。
ざっとした説明でしたが、参考になれば幸いです。また、間違いを見つけられた場合は指摘等も歓迎です。