• ベストアンサー

CGI(Perl)の文字化けについて

WEBフォームからの入力データをHTMLに加工して表示するというシンプルなCGIプログラムなのですが、 全角スペースの後に全角カタカナが入ると、全角スペースの部分から後が文字化けしてしまいます。 他はきちんと表示されているのですが、全角スペースとカタカナが続いているのが良くないみたいで、文字化けしてしまうようです。 全角スペースを取ってしまえばいいのかと思い、WEBで検索して色々と試してみましたが、変わりません。。 このような場合はどういう対処をするのが一番いいのでしょうか。 文字コードはEUCを使っています。(WEBフォーム、CGIとも) 教えてください。よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • petita
  • ベストアンサー率53% (8/15)
回答No.9

失礼しました。 $val=~s/(?<!\xA1)\xA1\xA5/\x2E/g; でいいと思いますが、J(j)code::tr を使う方が良いかもしれませんね。

noname#223023
質問者

お礼

petitaさん ご回答ありがとうございました。 教えて頂いたやり方で変換されていました! ありがとうございました! でもJ(j)code::tr を使う方がいいのですね。。

その他の回答 (9)

  • ryu_chan
  • ベストアンサー率37% (69/186)
回答No.10

現在は標準モジュールのEncodeを用いるのが一般的です。Encodeモジュールのdecode関数でテキスト文字列に変換してから文字列処理をします。 Encodeモジュールを使えば例えば以下のようにできます。 use Encode; $val = decode "euc-jp", $val; eval decode "euc-jp", '$val =~ tr/0-9A-Za-z@._-/0-9A-Za-z@._-/'; if($@) { エラー処理 } $val = encode "euc-jp", $val; JcodeはEncodeのラッパーなので、おそらくJcode内部では上記と同じような処理が行われています。ただし、既にJcodeを多用されているようなので、Jcodeで解決できればそれでいいとは思います。 文字化けの可能性は他にも沢山あり、今回の全角スペース+カタカナは氷山の一角です。No.9さんの「J(j)code::tr を使う方が良いかもしれませんね。」は、そのことも指しています。

noname#223023
質問者

お礼

ryu_chanさん ご回答ありがとうございました。 use Encode;を使うといいんですね! 今後のためにも調べてみます! 文字化けについては、これを使うと完璧!というのがないんですね。。 日本語はめんどくさいですね。。(笑) でも色々と勉強になりました! 皆様ありがとうございました!

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.8

> &Jcode::tr(\$val, '0-9A-Za-z-@._', '0-9A-Za-z-@._'); ↓ &Jcode::tr(\$val, '-0-9A-Za-z@._', '-0-9A-Za-z@._'); 見落としていたのですが、可能性としてハイフンの位置が悪いのかもしれません。置換文字列 '0-9A-Za-z-@._' の z と @ の間の - がエラーの原因になっている可能性があります。ハイフンを先頭または末尾に移動して試してみてはどうでしょうか? http://d.hatena.ne.jp/hiratara/20071226/1198685671 ネット上では Jcode の tr() はハイフンに弱いという情報があります (上記 URL)。面倒ですが、小分けにして書いてみてはどうでしょうか? 1つずつ追加しながら実行してみると、どこでエラーが発生しているのか分かるかもしれません。 $j = Jcode->new(\$val); $j->tr('0-9', '0-9'); $j->tr('A-Z', 'A-Z'); $j->tr('a-z', 'a-z'); $j->tr('@._', '@._'); $j->tr('-', '-');

noname#223023
質問者

お礼

kumozさん ご回答ありがとうございました。 &Jcode::tr(\$val, '-0-9A-Za-z@._', '-0-9A-Za-z@._'); ↑これで試させて頂いたところ、この部分で同じくInternet Server Errorになってしまいました。 $j = Jcode->new(\$val); $j->tr('0-9', '0-9'); $j->tr('A-Z', 'A-Z'); $j->tr('a-z', 'a-z'); $j->tr('@._', '@._'); $j->tr('-', '-'); ↑こちらはエラーにはならなかったのですが、特に変換されずにスルーされていました。 何か根本的におかしいのでしょうか。。。(泣 他に確認するところがありましたら教えてください。 よろしくお願いいたします。

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.7

> &jcode::tr(\$val, '0-9A-Za-z-@._', '0-9A-Za-z-@._'); 手元にテストできる環境がないので誤っているかもしれませんが、Jcode.pm では最初を大文字にして &Jcode::tr をまず試してみてください。(ちなみに、jcode.pl では最初の文字が小文字で &jcode::tr を使う。) 上記の方法を試してもダメな場合は、オブジェクト指向のやり方もあります。 $j = Jcode->new(\$val); $j->tr('0-9A-Za-z-@._', '0-9A-Za-z-@._');

noname#223023
質問者

お礼

kumozさん ご回答ありがとうございました。 はい、大文字にしてもダメだったのですが、もう一つ教えて頂いたコードを試してみましたがダメでした。(泣 もし他にやり方がありましたら教えてください。 よろしくお願いいたします。

  • kumoz
  • ベストアンサー率64% (120/185)
回答No.6

> #全角半角処理 > $val =~ s/\@/\@/g; > $val =~ s/\./\./g; > $val =~ s/\_/\_/g; > $val =~ s/\-/\-/g; EUC-JP では第1バイトと第2バイトに重複したコードが使われるので、上記のような正規表現は文字化けの危険が伴います。Jcode には tr() 関数が付属していまず。下記の URL に使い方が書いてありますので、参照ください。 http://mikeneko.creator.club.ne.jp/~lab/kcode/jcode.html http://openlab.jp/Jcode/Nihongo.html

noname#223023
質問者

お礼

kumozさん ご回答ありがとうございました。 教えて頂きましたサイトを見て、 このようにしてみましたが、エラーになってしまいました。。 このコードではいけないのでしょうか。。(泣 &jcode::tr(\$val, '0-9A-Za-z-@._', '0-9A-Za-z-@._'); ちなみに、Jcode.pmを使っています。

  • petita
  • ベストアンサー率53% (8/15)
回答No.5

$val=~s/\xA1{1}\xA5/\x2E/g;

noname#223023
質問者

お礼

petitaさん ご丁寧にありがとうございました。 早速試してみましたが、教えて頂いたコードを入れてみますと、 今度は全角スペース後のカタカナが文字化けしてしまい、戻ってしまいました。(泣 もちろん、このコード↓ $val =~ s/\./\./g; は削除しています。 この1行を入れるだけではダメなのでしょうか。 ちなみに、Jcode.pmを使っています。

  • petita
  • ベストアンサー率53% (8/15)
回答No.4

「 $val =~ s/\./\./g; 」 のところが原因です。 EUC-JP文字セットでは、全角空白は 「\xA1\xA1」、全角ピリオドは [\xA1\xA5]、全角カタカナの1バイト目は「\xA5」 だからです。

noname#223023
質問者

お礼

petitaさん ご回答ありがとうございました。 確かにその部分をコメントアウトしたら、カタカナが文字化けせずに表示されました! ありがとうございました! ちなみに、この場合はピリオドの変換はどのようにするのが良いのでしょうか。 良かったら教えてください。よろしくお願いいたします。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.3

>全角カタカナの場合、全角スペースの後に続くと文字化けしているみたいです。  これは経験がないのでわかりませんが、ありえない動作です。  該当するフォームと、Perlの処理部分、おび出力HTMLを見ないとなんとも・・  ローカルでテストできれば、それぞれの時点で print ERROR "line 152:$_\n"; とでもして、その時点での値を出力してみるとか・・

noname#223023
質問者

お礼

ORUKA1951さん ご回答ありがとうございました。 petitaさんがご回答してくださいましたが、ピリオドの変換が良くなかったみたいです。

  • ORUKA1951
  • ベストアンサー率45% (5062/11036)
回答No.2

>全角スペースとカタカナが続いているのが良くないみたい と >文字コードはEUCを使っています。 は矛盾してますけど。  EUCには半角カタカナはないです。EUC-JPにはありますが、それでも下記の問題を含んでいます。 EUC-JP ( http://ja.wikipedia.org/wiki/%E5%8D%8A%E8%A7%92%E3%82%AB%E3%83%8A#EUC-JP )  そもそも半角カタカナをHTMLに記述することには無理があり、半角カタカナを全角カタカナに変換するか、HTMLをUTF-8にするか、数値文字参照( HTML4 で使える文字実体参照 ( http://www.ne.jp/asahi/minazuki/bakera/html/reference/charref ) の下のほう)で記述することになるでしょう。  詳しい処理については、 Perlメモ ( http://www.din.or.jp/~ohzaki/perl.htm#JP_EUC_JP )の「日本語を扱う」の項目をご覧ください。  ま、Perl5.8以降なら、UTF-8に対応しているので、UTF-8で完結したほうが良いでしょう。(ライブラリは使わなくてすむ)

noname#223023
質問者

お礼

ORUKA1951さん ご回答ありがとうございました。 半角カタカナが入力された場合は全角カタカナに変換するようにしているので、 半角の場合は問題ないのですが、全角カタカナの場合、全角スペースの後に続くと文字化けしているみたいです。 ちなみに半角スペースの後の全角カタカナは文字化けしないようです。 他の入力フォームでも使っているので、出来たらEUCの文字コードのまま使いたいのですが、UTF-8にした方がいいでしょうか。。

回答No.1

フォーム画面およびCGIともにEUCなら、全角スペース関連で化けるということはあまりないような気がします。 CGI側でフォームから送られたデータを変数に格納している部分があると思いますが、そのライブラリなどは何をお使いですか?そのあたりからヒントが得られるかもしれません。 まずは全部でなくていいので、入力データのデコード部分と実際の表示部分のソースを見せていただくことは可能ですか?

noname#223023
質問者

お礼

gadgetwatchさん ご返答ありがとうございました。 全角スペースの後にカタカナ、 半角スペースの後にカタカナ、 スペース無しの後にカタカナ で調べてみたら、全角スペースの後にカタカナの時のみ文字化けしていました。 日本語処理ライブラリはJcode.pmを使っています。 デコード部分です。 $val =~ tr/+/ /; $val =~ s/%([0-9a-fA-F]{2})/pack("C",hex($1))/eg; if($opt){ #英数字全角半角処理 $a = qr{(?<!\x8F)}; $b = qr{(?=(?:[\xA1-\xFE][\xA1-\xFE])*(?:[\x00-\x7F\x8E\x8F]|\z))}x; $val =~ s/$a\xA3([\xB0-\xB9\xC1-\xDA\xE1-\xFA])$b/pack("C", ord($1) - 0x80)/oeg; #全角半角処理 $val =~ s/\@/\@/g; $val =~ s/\./\./g; $val =~ s/\_/\_/g; $val =~ s/\-/\-/g; 表示部分は、 &Jcode::convert(\$text, 'euc'); HTMLに加工したものをEUCにして表示するようにしています。 (あまり必要ないかもしれませんが。。) これで足りますでしょうか。 よろしくお願いいたします。