仕様だからしようがないんです。(誰かに思いっきり殴られそう…) とまあ、こんなことを書くんだったら最初から書くなと 怒鳴られそうなので、原因とその解決法を提示しておきます。 ある特定の文字でパーサエラーなどが起きるのは文字コードの問題です。 この問題は主にSJISなどで書かれたソースコード中にマルチバイト文字で 後半のバイト部分に0x5Cが含まれている場合に発生します。(よく言う5C問題。 #マルチバイトの前半部をLead byteと、後半部をTrail byteというらしい。 具体的例を挙げます。PHPスクリプトの文字コードがSJISである環境において 「ソ」「表」はそれぞれ「83 5C」「95 5C」というマルチバイトで構成されています。 この後半にある「5C」の部分でパーザ側がSJISのシングルバイトで「5C」の 「\」(特殊な符号)だと解釈してしまい、その結果期待しない動作を引き起こしています。 端的に言うとSJISで0x5Cは\に相当していてマルチバイトでもその部分が扱われている! PHPマニュアルにもこれに関することが載っています。 「PHP: マルチバイト文字列関数 (mbstring) - Manual」 http://www.php.net/manual/ja/ref.mbstring.php#mbstring.php4.req また、文字コードの問題に影響している一つとしてereg関数が挙げられます。 PHPは基本シングルバイトでの処理なので、マルチバイトの文字列を処理する場合には mb_*関数(マルチバイトに対応した関数)を使用しなければなりません。 先に述べた例にあるように1バイト単位で読み取る場合、0x5Cは\と解釈されるので 正規表現中に\が存在してしまうことになります。この結果、マッチして欲しい 文字列に対して無反応といった現象が起きます。以下にregexの説明を書きます。 '\'に続けて'^.[$()|*+?{\'のいずれかの文字を入力することで、それらは 普通の文字としてマッチします。また、'\'に続くその他の文字については、 '\'が付いていないときと同じ普通の文字としてマッチします。 最後が'\'で終わるのは、正規表現では違反です。 以下のサイトを参考に文字'\'に関する部分を意訳してみました。 >> regexのmanページ http://www.tin.org/bin/man.cgi?section=7&topic=regex 明らかに違う文字列を比較しているはずなのに、 内部的には一緒なので期待しない動作をする例を挙げます。 ereg("事","月明") TRUE mb_ereg("事","月明") FALSE #$a="\x8E\x96";$b="\x8C\x8E\x96\xBE";プログラム内でわかりやすく表すとこうなる。 #--enable-zend-multibyte したものだと上記のものうまく変換されないね…。何故に? #関数の戻り値は1かFALSEみたいだけど、わかりやすくするためにTRUEにしてます。 #今回の質問では、この関数の動作に関係していると思います。 これらの問題の対策として、次のような方法が考えられます。 (1)PHPスクリプトの文字コードをUTF-8かEUC-JPに変更する。 (2)--enable-zend-multibyte を有効にし、スクリプトの文字コードを指定する。 (3)その場しのぎで問題の文字をエスケープしてみる。 めんどくさい事はキライッ!って方には(1)をお勧めします。 #WinXPやw2k以降はUTF-8でもメモ帳で開けるはずです。 うち、何でもSJISじゃないとダメなの!って方には(2)をお勧めします。 #SJISで問題なく書けます。"表"と書いてもちゃんと解釈してくれます。 で(3)についてですが、問題を十分理解していない人にはお勧めできません。 まあ、特に理由がない限り(1)を選択しましょう。(そろそろUTF-8に切り替え時かな… #(3)の方法で"表"は"がエスケープされることになってエラーになるので、"表\"にするけど #"表計算"は何とか読むみたい。"表\計算"をbin2hex関数で確認してみても一緒の結果。 #んー、まだPHPエンジンの仕様が把握できていないみたいです…。 ただ、いずれの場合でも正規表現で日本語を扱う場合は、ereg関数ではなく別の マルチバイトに対応した関数にしたほうが良いでしょう。SJISなどは特に。 この場合はmb_ereg関数に変更すればおkです。関数のオーバーロードもあり。 ただし、PHP4においてUTF-8な環境でmb_ereg関数を使用する場合は注意が必要です。 間違いが含まれている可能性がありますので、自分で調べてみることもしてください。 明らかにおかしなところやツッコミがあれば何なりと。 参考になりそうな記事ないかなーと思ったら、こんなのがありました。 「PHPの文字化けを本気で解決する」 http://hain.jp/index.php/tech-j/2007/02/13/p125#more125 「マルチバイト対応正規表現関数(mb_ereg系)でUTF-8の文字列が正しく処理できない件について」 http://d.hatena.ne.jp/masugata/20061213#p2 「zend-multibyteの挙動について」 http://ml.php.gr.jp/pipermail/php-dev/2003-May/thread.html 動作確認した環境: w2ksp4, Apache2.0.59, PHP4.4.5, PHP4.4.4(マルチバイト対応版) #「マルチバイト対応版PHP4」を使おうとしたら、Apacheがクラッシュしてしまい #その原因を追究するのに無駄に時間を掛けていたという…orz #入手先:http://www.geocities.jp/rui_hirokawa/php/win/ #Apache/1.3.34 (Win32) PHP/4.4.4 running... #dumpbin.exe でスタックサイズを確認しても問題なし。 #本家のPHP4.4.4では同じような設定で問題なし。extension_dirも確認済み。 #で php4apache.dll を読み込ませ、PHPを実行するとApacheの子プロセス即死。 #結局のところApache2.0.59でちゃんと動いたのだけど、原因わからず…。 #環境がごちゃごちゃしているから、そのせいかもしれない…。 #文字化けの原因がわからないときは素直にUTF-8を使うのが得策。 #EUC-JPより最近はUTF-8な傾向ですので…。まあ、いい傾向かな? #PHP6からはUnicodeネーティブ対応みたい。ちょっと期待してみる…。 #んー、全部読むのめんどくさいですね。でも、書くのもめんどくさかったよ…。 #もしかすると説明が足りてない部分があるかもです…。よくわからないところは言ってね。 a `\' followed by one of the characters `^.[$()|*+?{\' (matching that character taken as an ordinary character), a `\' followed by any other character(!) (matching that character taken as an ordinary character, as if the `\' had not been present(!)), or a single character with no other signifi- cance (matching that character). It is illegal to end an RE with `\'. >> regexのmanページ http://www.tin.org/bin/man.cgi?section=7&topic=regex PHP4:mbregex(マルチバイト対応正規表現関数)・ PHP5:鬼車(マルチバイト正規表現ライブラリ) printf("%X", ord(String)); eMbedded Visual C++ 4.0 から必要なバイナリを抜き取る際のメモ. dumpbin.exe と editbin.exe の実行には link.exe と mspdb60.dll が必要. link.exe が欠けている場合に以下のようなエラーが出る. dumpbin: invalid option -- d Try `dumpbin --help' for more information. 必要なファイルはすべて以下のフォルダ内に入っている. WCE/wce400/BIN/ D:\Apache>dumpbin /headers Apache.exe | grep stack 100000 size of stack reserve 1000 size of stack commit D:\Apache>editbin /STACK:393216 Apache.exe Microsoft (R) COFF/PE Editor Version 6.24.1243 Copyright (C) Microsoft Corporation. All rights reserved. D:\Apache>dumpbin /headers Apache.exe | grep stack 60000 size of stack reserve 1000 size of stack commit D:\Apache>