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:上のコードでもこのモジュールをちゃっかり使ってるけど