【PR】 家電品の安さ、品揃えに自信あり! 【PR】 ターボセルでセルライト対策 【PR】 中国語学習に役立つサイト 【PR】 ディズニーの英語システムなど英語リスニング教材比較 |
||||||
・CGIで特定の文字(表・予・申・能など)が文字化けする自動バックアップ・テスサーバー付きの新機能スマートリリース CGIやPHPなどの技術系でSuper FAQ(よくある質問)がこれです。下記のような文字化けが発生します。 文字化けしている漢字は「表」「予」「申」「能」「十」「ソ」などです。第1章の「Netscape4.Xのdocument.write時の文字化け」は音が「シ」のものに集中的に文字化けが見られるなど、顕著な規則性がありました。今回の文字化けは、「音」が似通っているという特色はありません。 しかし、それぞれの漢字のShift_JISコードを調べてみると、ある規則性が浮かび上がってきます。Shift_JISコードを調べるには、序論で紹介したようなIMEやことえりの文字一覧表でもいいのですが、ここではURLエンコードを利用してみます。 URLエンコードは、プログラマーでない方にはなじみがないでしょうが、実は日ごろ気がつかないうちに利用しているんです。検索エンジン(サーチエンジン)などで検索した時に、日本語などを検索キーワードとしてプログラムにGET方式で引き渡す際に、日本語のまま引数として渡すと具合が悪いので、日本語部分を16進数のコードに変換して、http://www.example.com/search.cgi?keywords=%82%A0%82%A2%82%A4%82%A6%82%A8などにアクセスする形でパラメータを渡しています。例えば、「%82%A0%82%A2%82%A4%82%A6%82%A8」とは「あいうえお」のURLエンコードした結果となります。あ = %82%A0」(1バイト目のコードが82、2バイト目のコードがA0)となります。
URLエンコードするには、サーバ上でCGI・PHPなどで変換することもできますが、ここではFlashを利用してみます。下記の駄作フォームに文字を入力し、URLエンコードというボタンをクリックするとエンコードできます。ただし、これはあくまでもShift_JISでの話です。ちなみに、Javascriptでもescape関数というのがありますが、確かにネットスケープではURLエンコードできますが、IEではunicodeに変換する関数になっています。互換性がありません。そこで、ローカルで動くもので、かつIEでもネットスケープでも動くものをということで、Flashで作成してみました。Flashは専門でいないので、思いっきり不細工ですがご了承ください。
|
これだけ並べてみると、何か規則性は見えてこないでしょうか? そう、2バイト目が「5C」というコードになっています。「5C」を1バイト文字だと考えると、「\」です。「\」はプログラム内では特別な意味を持つことは、プログラムをされている方なら誰もがご存知だと思います。メタ文字と言われ、エスケープ処理をされる場合に使います。 ここでエスケープ処理の復習をしてみましょう。例えば、「私の名前は"田中太郎"です。」とprintしたいとします。この場合に、シングルクォーテーションを使うのも手ですが、もしダブルクォーテーションを使う場合に、print文の終わり(printされる目的語の範囲ともいうべきもの)が分からなくなってしまいます(結果的には、parse errorになります)。そこで、「print "私の名前は\"田中太郎\"です。";」とします。これにより、「田中太郎」をはさむダブルクォーテーションは、決してprint文の終わりを示す符号ではなく、単なる文字ですよとなります。 では、「print "私の名前は田中太\郎です。";」とすると、どう表示されるでしょうか? ここでは、「\マーク」は無視され、「私の名前は田中太郎です。」と出力されます。エスケープが必要のない文字の前に「\マーク」をつけても無視されるわけです。では、「\マーク」自体を出力したい場合はどうするかといいますと、「print "このりんごの値段は\\100です。";」とします。「\(円マーク)」の前に、メタ文字としての「\」をつけて、後ろの文字の「\」は文字通りの「\」だよという命令を出します。 ここまでが文字化け発生メカニズム解析のための下準備です。例えば、「可能性」という単語がなぜ「可柏ォ」(「ォ」は本当は小さい「オ」の半角カタカナ)に化けるのかについて調べてみます。
ここで、下調べで分かったことを取り入れると、下記のような変形になる。化学反応式のように分離結合が起こる。5Cがメタ文字として無視される結果
同様に、「申請書」がいかにして、「瑞ソ書」(実際にはソは半角カタカナ)に化けるのかを検証してみます。
申請書 = 905C + 90BF + 8F91 = (90 + 5C) + (90 + BF) + 8F91 = (90 + 90) + BF + (8F + 91) ここで、「90 90」なる漢字は、上のURLデコーダーで調べてみれば、「%90%90」→「瑞」と分かります。同様に「%BF」とは「ソ」の半角カタカナですから、やはり"合理的に"文字化けしていることが分かります。 では、これらの文字も化けないようにするのにはどうしたら良いのでしょうか? それは2バイト目にある「5C」というコードはメタ文字ではないですよと教えてあげればいいことになります。「\」が一つのために、「\」が消えてしまって、文字化けしてしまっていたのですから、もう一つ「\」をつけてあげれば良いことになります。すなわち、「print "表\示";」「print "予\定";」「print "可能\性"」としてあげれば良いのです。 ただ、一々文字化けする可能性のある漢字に対して、エスケープ処理をしないといけませんので、これは面倒です。そもそも、このように、「5C」というコードを2バイト目に持つ漢字は、どれぐらいあるのでしょうか? 調べてみると下記のように全部で40文字あります。
※ の3文字は機種依存文字。Windowsではテキストでそのまま表示されますが、Macで表示するためには画像などに変換する必要があり、ここでは画像ファイルを用いています。機種依存文字については、別章を参照してください。
滅多に使わない漢字も多いですので、実質は10文字から15文字も覚えていれば実用上は事足りるかもしれません。しかしながら、こういうエスケープ処理を一切しないでもいい方法が二つあります。一つは、問題のある漢字を含む文字列をprintする際に、ダブルクォーテーションではなくシングルクォーテーションで囲んでprintすることです。つまり、「print '表現
(ただし、出力されるソースが綺麗に改行されるようにと、「print '表現 もう一つの方法は、文字コードをShift_JISではなく、EUC-JPで作成することです。EUC-JPの漢字にはメタ文字は、現れません。ですから、エスケープ処理が必要ありません。もちろん、i-modeサイトの構築時や、デザイナーとの仕事の連携の関係でどうしてもShift_JISで開発しなければならない場合もあるでしょうが、それ以外の時はEUC-JPでプログラムは作成したほうが絶対的に無難です。 特に正規表現を用いる必要がある場合は、Shift_JISでプログラミングすると考慮しなければならないことが多すぎて大変です。このホームページの目的は文字化けの原因究明ですので、正規表現についての考察はしませんが、これらの問題点についての説明は、
● Shift_JISテキストを正しく扱う
● Perlメモ:日本語を扱う perl スクリプトは EUC-JP で書く
話を元に戻します。さらに文字の化け方を考察してみましょう。
また、HTMLタグの「<」が化けると、本来改行があるべきところが改行されなかったりなど(例:機構<br>→機・br>)、レイアウトが崩れる原因になります。例えば、それが<input type=hidden〜>で渡す情報であれば、hiddenの内容は送信されず誤作動の原因になります。したがって、単なる文字化けで済まされない可能性があります。
このMagic Quotes GPCの問題を考えても、Shift_JISでプログラミングするのは、文字コード全般の知識を有している場合やi-モードサイトの構築などでどうしても避けられない場合などを除いては避けるべきです。(もちろんMagic Quotes GPCをoffにすれば、この問題は発生しません。あなたがサーバの管理者でない場合も、.htaccessで設定可能です。「php_flag magic_quotes_gpc off」とすればOKです。データベース登録時には、addslashesなどの処理が必要です。) 次のページからは、機種依存文字について説明します。まずは、Windowsでは表示可能でもMacでは文字化けする文字について考察します。
|