Mac OS Xのファイル名の文字エンコーディングはUTF-8になってる。このファイル名をEUC-JPとかの他のエンコーディングに変換するときに、そのままだとおかしくなる。
どうも原因は、Mac OS Xではひらがなやカタカナの濁音や半濁音を表すのに、二つの文字を組み合わせるようにしているからのよう。EUC-JPではそれらの文字は一つの文字として扱うようにしているので、うまく変換できない。ためしに再現してみるのに、以下のようなPerlのコードを用意してみた。
use warnings; use strict; use Encode; use Unicode::Normalize; my $str = "スマイルギャング"; my $norm = decode_utf8($str); my $osx = NFD($norm); # 濁音を二つの文字を組み合わせて表す print encode('euc-jp', $norm, Encode::PERLQQ),"\n"; print encode('euc-jp', $osx, Encode::PERLQQ),"\n";
これを実行すると、
スマイルギャング スマイルキ\x{3099}ャンク\x{3099}
となって、Mac OS Xのファイル名形式の文字列では、濁点の部分がEUC-JPに変換できてないことがわかる。んじゃ、Mac OS Xのファイル名を受け取ったときにほかのエンコーディング変換するにはどうすれば良いか。それにはUncode::Normalizeというモジュールが用意されているので、そのモジュールのNFKCという関数を使う。*1
use warnings; use strict; use Encode; use Unicode::Normalize; # Unicodeの正規化を行うモジュール my $str = "スマイルギャング"; my $norm = decode_utf8($str); my $osx = NFD($norm); # 濁音を二つの文字を組み合わせて表す $osx = NFKC($osx); # 濁音を一文字で表すように変換 print encode('euc-jp', $norm, Encode::PERLQQ),"\n"; print encode('euc-jp', $osx, Encode::PERLQQ),"\n";
これで、
スマイルギャング スマイルギャング
と表示されて、うまくEUC-JPに変換できた。
perl5.8のUnicodeサポートをかなり参考にしたので、くわしくはそちらで。
*1:上のコードでもこのモジュールをちゃっかり使ってるけど