人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Perl utf8モジュールの効果と文字化けについて

Perl言語を活用しまして、外部サイトのRSSファイルを取得し、その取得したRSSの内容を当方のサイトに出力したいと思っております。
RSSを取得するモジュールとして「XML::FeedPP」というモジュールを活用します。(http://www.kawa.net/works/perl/feedpp/feedpp.html)
今回の質問はutf8モジュールを使用したときに特定の条件で文字化けがおきる理由が知りたいということです。
以下に、RSSファイルを取得しサイトに出力する4つのケースを記述します。(すべてUTF8コード)

ケース1、http://nichista.seesaa.net/image/case1.txt
ケース2、http://nichista.seesaa.net/image/case2.txt
ケース3、http://nichista.seesaa.net/image/case3.txt
ケース4、http://nichista.seesaa.net/image/case4.txt

さて、途中の13行目から「#ケース1?4)」の部分を変更して複数の条件でプログラムを走らせます。
上記の4つのケースのうち、「ケース3」のみ文字化けしてしまいます。
しかし、なぜ「ケース3」だけこのような文字化け現象がおきるのでしょうか?
この現象の理由を知りたく存じます。

●質問者: nagato-yuki
●カテゴリ:インターネット ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● うぃんど
●300ポイント ベストアンサー

外部のページを参照するのは面倒なので、まずは1つにまとめさせてもらいました

#!/usr/bin/perl
use utf8;
use strict;
use XML::FeedPP;

print "Content-type: text/html\n\n";
print "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html\; charset=UTF-8\"><title>test</title></head><body>\n";
my $source = 'http://www.nicovideo.jp/ranking/fav/daily/g_popular?rss=2.0';
my $feed = XML::FeedPP->new( $source );
print "Title: ", $feed->title(), "<br />\n";
foreach my $item ( $feed->get_item() ) {

#ケース1
print "Title: ", $item->title(), "<br />";
#ケース1

#ケース2
my $stock = $item->title();
print "Title: $stock<br />";
#ケース2

#ケース3
my $stock = $item->title();
print "タイトル: $stock<br />";
#ケース3

#ケース4
my $stock = $item->title();
utf8::decode($stock);
print "タイトル: $stock<br />";
#ケース4

}
print "</body></html>\n";
exit;

さて、本題への答えですが、外部から読み込んだものは、

そのキャラクタセットなどには一切関知せず、

「そのままの形」で保持されていることが原因となっています

対処例から述べますと、use open IN などで、

「外部から読み込んだものはutf-8として取り扱う」といった、

フラグを立てるようにするなどします

ケース1および2では、

Titleという半角英数字との組み合わせであるために、特に問題は発生せず、

ケース4においては、

単独でフラグを立ててやってますので、これまた問題は発生せず、

問題のケース3では、

日本語との組み合わせになっているため、

そのままの形でつかってくれれば良いものを・・・

気を利かせて(というのは言葉のアヤですが)変換しようとしてしまうようなのです

参考

http://www.rwds.net/kuroita/program/Perl_unicode.html


うぃんどさんのコメント
追記: ブラウザによっては、HTMLのMETAタグにだけUTF-8などと指定しても、 正常にキャラクタセットを認識できない場合があるため、 httpヘッダーでもキャラクタセットを指定しておくほうがベター

nagato-yukiさんのコメント
ご回答、及び追加コメントありがとうございます。 なるほど、外部読込みの場合は文字コードを関知せずに、 そのままの形で取り込まれているのですね。 結果、utf8モジュールを使用しutf8フラグを立てないままでは 「ケース3」の場合、マルチバイトと認識せずにシングルバイトとして認識・出力されてしまう、ということが理解できました。 わがままで恐縮ですが、もう少し詳しくご教授いただきたい部分がございます。 ケース3では、”タイトル:”という文字列にフラグが立っているため、後のフラグなし変数をシングルバイト変換してしまうことが分かります。 それでは、ケース2の場合、utf8モジュールは”Title:”という文字列にフラグを立てず、後の変数もそのままの形で出力している、ということなのでしょうか? print "(半角英数)+(日本語を含む変数)"; (ケース2) print "(日本語)+(日本語を含む変数)"; (ケース3) (半角英数)(日本語)にフラグが付くかどうかによって、後の(日本語を含む変数)にutf8モジュールがどのような判断をしているのでしょうか? 度々の質問で申し訳ございませんが、お答えいただけると幸いです。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ