くれすのPerl日記 このページをアンテナに追加 RSSフィード

この日記の方針。

  1. この日記では、超初心者向けの内容は取り扱っておりません。モジュールの利用など、実践的な内容が中心となります。
  2. ここに貼られるソースは、基本的にそのままでは動かないものばかりです。各自の責任でご利用ください。
  3. 内容が間違っていることがあります。その際はご指摘いただけるとありがたいです。「検証してみたら違う結果が出た」などの報告も大歓迎です。
  4. perl -e die

2006-08-29 (Tue)どーなってんの日本語

[] どーなってんのShift_JIS 10:09  どーなってんのShift_JIS - くれすのPerl日記 を含むブックマーク はてなブックマーク -  どーなってんのShift_JIS - くれすのPerl日記  どーなってんのShift_JIS - くれすのPerl日記 のブックマークコメント

昨晩、LWP::UserAgentでファイルを取得してArchive::Zipで固めるというCGIリリース・・・しようとしたら、日本語の問題*1でつまづきました。

Shift_JISで書かれたファイルから1行ずつ読んでファイル名にしようとしてもうまく行かない。内部的な問題かと思い、Encode::from_to でUTF-8*2に変換して、ファイル名を作ってから再び戻すという処理をやってみたが、これもやはりうまく行かない。

ソースShift_JISで書いていると「表示」を「表\示」とかやらないといけないのは有名な話だが。どうもそれとは違うらしい。0x5C*3 が入っていない文字列も、全部失敗している。

調べたところ、Encode::from_to でShift_JISに変換するところに問題があったらしい。

色々試したところ、UTF-8からShift_JISへの変換で、
Encode::from_to($str, 'utf8', 'shiftjis', Encode::FB_HTMLCREF);
では変換に失敗するけれど、
$str = encode('shiftjis', decode('utf8', $str), Encode::FB_HTMLCREF);
であれば、正しく変換(かつ、Shift_JISに無い文字はHTMLの数値文字参照に変換)されるようでした。 Encode::FB_HTMLCREFの変

この結果、こうなりました。

# 注:抜粋。単体では動きません。
while( my $line = <IN> ) {
    next if( $line =~ /^\s*$/ );  # 空行無視してね。
    Encode::from_to( $line, 'sjis', 'UTF-8' );
    $line =~ s/[\r\n]//g;
    my( $srcfile, $destfile ) = ( $line =~ /^([^\s\t]+)[\s\t]*(.*)$/ );

    # destfileに拡張子を付ける。
    my( $ext ) = ( $srcfile =~ /\.([^\.]*)$/ );
    $destfile = sprintf( '%s.%s', $destfile, $ext )
        if( $destfile !~ /\.$ext$/ );
    # Encode::from_to( $destfile, 'UTF-8', 'sjis' );
    $destfile = Encode::encode('shift_jis', Encode::decode('utf8', $destfile), Encode::FB_HTMLCREF);

    push( @$list, { src => $srcfile, dest => $destfile || $srcfile } );
}

難しいことはわかりません。でも動いたのでOKです*4

で、完成したCGIって?

Sky RiverというMIDI音楽サイト(個人)の一括ダウンロードの管理画面になりました。本館リンクのページからどうぞ。

どうでも良いんだけど

use Encode;

ってやると、暗黙の了解で Encode::JP も読み込まれるらしい。

わけわからん。

追記

これ、変でした。

$destfile = Encode::encode('shift_jis', Encode::decode('utf8', $destfile), Encode::FB_HTMLCREF);

第3引数要りません。HTML用にエスケープされちゃったら大変。

もうひとつ。こっちはArchive::Zipの問題かどうか不明なのだが。

Windowsエクスプローラで開くと化けます。化けた文字は・・・「十」。すなわち、2バイト目が 0x5C!どーしたらいいものやら。

ソースが結構汚い*5ので、後日書き直します。

*1:決して、私の日本語が不自由というわけではない。と思う。

*2Perlソースは基本的にUTF-8で書いています。

*3バックスラッシュ日本語Windowsでは¥。いわゆるエスケープ文字ね。

*4:良いのか、それで・・・

*5:途中からやっつけになってる・・・

トラックバック - http://perl.g.hatena.ne.jp/Cress/20060829