- ベストアンサー
preg_matchでの コンマ について
phpでの正規表現で 「もしも変数$wordへ入力した文字列が Japan's という文字列に一致すれば」というスクリプトを作成しましたが、うまくいきません。 if(preg_match("/japan\'s/i",$word,$match)){ この Japan's における カンマの取り扱いを このケースではどうしたらいいかよくわかりません。 \' としてみましたが、うまくいきません。 なにかアドバイスやヒントがありましたら、よろしくお願いします。 ああでもない、こうでもないとやってみましたが、その過程で 唯一 Japan's にヒットしたのは、次のスクリプトでした。 if($word=="japan\'s") ただし、これは正規表現は使っていないわけですよね。 なにか、自分のローカル環境に問題があるのかと思い、レンタルサーバーに同じものをuploadして試して見ましたが、やはり結果は同じで、ヒットしませんでした。別のパソコンでもやってみましたが、結果は同じでした。 整理しますと、 (preg_match("/japan's/i",$word,$match) ではヒットせず、よって コンマの前に\をつけて(preg_match("/japan\'s/i",$word,$match) としましたが、これもヒットしなかったということになります。 1) (')は正規表現の特殊文字でないはずですから、そのまま使えるはずだと思いましたが、なぜかこれが使えない。 2) しかも、その前にエスケープの \ をつけても、そのエスケープ が効かないのはなぜか。 追記: 最近分かったこと。 おもしろいことに、 'j すると、hitする。でも、j' とするとヒットしない。 ということは、コンマ自体には問題ないのだろうと推測しています。でも、文字の後にコンマがつくと、preg_matchにとって特別な意味を持つ文字列に変わるのではないか。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
stripslashesを使ってうまくいったようでよかったです。 それは正しい対応の仕方の一つだと思います。 私の前回のコメントで ~つまり、"\"が入っているのを外してから処理するとか~ と書いているのが具体的にはまさにその方法です。 この(マッチング)問題はこれで完結ということでもよいと思います。 ただ、magic quotesが理由なのか、仮にそうだとしてmagic quotesがなぜonになっているのか、というのはシステムを自分の制御下に置くという意味で確認しておきたいところです。といって、あまり拘ることでもないので自分のやりたいことを優先して、magic quotes設定の確認はおいおいやっていけばよいでしょう。 ANo.5へのお礼で教えていただいたwebページの最初の方にmagic_quotes_gpcの状態がどうなっているかを確認するphpコードがあります。これを実行してみて実際にはどうなっているのかを確認しておくとよいと思います。 もし、(php.iniでoffに設定しているのに)magic_quotesがonになっているのなら実は違うphp.iniなど別の設定が有効になっている可能性があります。もし、magic_quotes_gpcがきちんとoffになっているのなら、'\'が入ってしまう原因はmagic_quotes_gpc以外にあるということです。 ご存じかもしれませんが、phpinfo()という関数を実行するとそのphp処理系の状況を表示することができます。 <?php phpinfo(); ?> というphpコードを書いて実行させればOKです。これでmagic quotesの状況を含め、色々な設定がどういう状況になっているかを確認しておくのもよいでしょう。
その他の回答 (5)
- dummyplug
- ベストアンサー率58% (134/230)
ANo.4でコメントしたものです。 (追加の回答を書いたつもりだったのですけれど、今みたら追記されていないように見えるので念のため同内容でもう一度書きます。回答を書いたときにうっかり最後の「確認」ボタンを押さないでブラウザを閉じてしまったのかも知れません。) その後、考えてみたのですが、magic quoteなのかもしれません。 MS Windows版だと\Windowsか\Windows\System32にphp.iniがあると思います。 そのファイルの中で"magic_quotes_..."で始まる行を探してください。 いくつかあると思いますが、その中で"On"に設定されているものはありますか?一番怪しいのは"magic_quotes_gpc"です。 この設定をOnにしておくと、自動的に"'"(シングルクォーテーションマーク)の前に"\"(バックスラッシュ)を入れてくれるようになります。が、今回の場合はむしろ邪魔だと思いますので、Offに設定してください。 この設定をOnにしておきたいこともあるかも知れませんが、その場合はそれを前提としてコーディングしないといけません。つまり、"\"が入っているのを外してから処理するとか、"\"が入っているのに対応した処理をする(今回の場合だとpreg_match()のマッチング文字列を対応するように書き直す)という考慮をしないといけません。 magic quotes(の設定がOnになっている)が原因でないとしたらまたちょっと考えます。いずれにしても環境設定系(php.ini)まわりではないかと考えているのですが…。
お礼
magic_quote 教えていただいて、ありがとうございました。 それについて ネット上で色々調べていて、 つぎのことを実行することによって、とりあえず pre-matchで japan's が ヒットするようになりました。 $word = stripslashes($_POST['data4']); という一文を いれたのです。 http://www.tizag.com/phpT/php-magic-quotes.php なんとか これでいけそうな感じがします。 ---------------------- <form action="p02.php" method="post"> <input type="text" name="data4" size="5"><input type="submit" value="入力"> </form> <?php $word = $_POST['data4']; $word = stripslashes($_POST['data4']); if(preg_match("/japan's/i",$word,$match)){ echo "正解です "; var_dump ($match);} else { echo "残念でした "; var_dump ($match); } ?>
補足
dummyplugさま、 本当にたびたびすみません、恐縮しております。 それと返事が遅くなって申しわけありませんでした。 さっそく 述べられていることをやってみました。 php.ini は、今回のわたしのは XAMPPからのインストールですので、apache関連などのファイルと共に すべて同じfolderに格納されていました。 magic_quotes_gpcについて、On になっているのを Off に切り換えてみましたが、残念ながら結果は同じで、single quotation の隣に \ が挿入されてしまいました。 いまのところ、正規表現を使って if(preg_match("/japan.*'s/i",$word,$match)){ と書くことによって、japan's のような単語に対処しようと思っています。 こういう現象が起きるのは、 preg-matchの部分だけですので、とりあえずは便宜的ですが これでいいかと思っています。 しかし、これは根本解決ではありませんので、なんとか解決できればありがたいです。 それにしても、なんでこんなことが私の二台のパソコンに起こっているのか、どう考えても その原因となるようなことが思いつかないんですよね。 もしかしたら、 php などの範囲外からの影響を受けているのかと 不安が広がってしまいます。
- dummyplug
- ベストアンサー率58% (134/230)
ANo.1,2でコメントした者です。 >あなたが入力したのは「japan\'s」ですね。残念でした array(0) { } なるほど。うーん。。。 フォームで入力したのは"japan's"という文字列なのですよね? 試してもらったecho文をこんな風に変えてみてください。 echo "あなたが入力した文字列の5,6,7文字目は「", substr($word, 4, 3), "」です。" その状態で、フォームでjapan'sと入力するとおそらくこう表示されるのでしょう。 あなたが入力した文字列の5,6,7文字目は「n\'」です。 これは何を意味しているかというと、入力した文字列が"japan's"なのにも関わらず、PHPのコードに届いた($word変数に入った)文字列には"'"の前に(余計な)"\"が入ってしまっている、ということです。この表示されている"\"はエスケープなどではなく、本当の文字として一文字入ってしまっているということです。(だから、substr()で3文字取り出すとそのうちの一文字としてカウントされているのです。その意味では$wordの文字列長を表示してもよいですね。"japan's"なら7文字でないといけないのに8文字と表示されることでしょう。) これではマッチしません。 仮に、この入力にどうしてもマッチさせようとしたら if (preg_match("/japan\\\\'s/i", $word, ... と書くことになります。(この場合に限っては"/japan\\\'s/i"でもよかったりしますが、本質と外れるので説明は割愛します。このこととか、"\"が4つも必要な理由とか気になるようなら補足か何かで訊いてくれれば説明します。) いずれにしても、入力された文字列に余計な"\"が入ってしまうのが謎です。こちらでも考えてみますが、思い当たることは何かないでしょうか。 ちなみに、私のところであなたのコードを動かしてみましたが$word変数には(フォームに"japan's"と入力すれば)"japan's"と余計な"\"が入ることなく値がセットされ、もちろんその後のpreg_match()も成功しました。 PHPの実行環境はFC8(Linux)でPHP5.2.4、httpd(apache)は2.2.8でアクセスしたブラウザはFireFox 2.0とIE6.0です。 間違いがないよう、あなたのコードをcopy&pasteでサーバに持ち込んで動かしています。なのでコードは一字一句同じはずです。 …はずなんですが、なんで違いが出るのでしょうねぇ。 とにかく、preg_match()で使っている正規表現には問題なさそうです。問題は、「入力された文字列に余計な"\"が入ってしまう」ことにあります。 こちらを追ってみてください。
補足
なんども貴重な情報、ヒント、アドバイスありがとうございます。 深いですね。書かれていることが。 if(preg_match("/japan's/",$word,$match)) というスクリプトで、それに 述べられているスクリプトを追加し、japan's と入力してみました。 表示させた結果はつぎの通りです。 あなたが入力した文字列の5,6,7文字目は「n\'」です。 たしかに、おっしゃる通りになりました。 どうしてこうなってしまうのか。 > 本当の文字として一文字入ってしまっているということです ということは、どこかでそのように設定されてしまっているということなんでしょぅかね。 文字列' の場合は、\を追加するような設定がどこかでされてしまっているとか。 それについては、まったく見当すらつかないんですよね。 今回は 間接的ですが、ロール環境の点から 自分なりに この問題に迫ろうとしてみました。 対処療法ですが、二つあるうちの一方のパソコンの php と apacheのファイルを注意深く、そして完全にuninstallし、さらにほぼ一ヶ月前までシステム復元をした上で、 改めてxammpからphp と apacheを installしてみました。そして、すぐに例のスクリプトを実行してみましたが、やはり結果は同じでした。 installした php や apacheに原因があるのか、あるいはinstallするさいの手続きに問題があるのか。とはいっても、 今回はxammpからinstallしたわけですが、 それはひじょうに簡単なものですので、そこに問題があるとは考えにくい。 phpをパソコンに 私にとって初めて搭載してからまだ一ヶ月もたっていませんが、そのときにinstallしたときは、 xammpではなく、 http://w1.nirai.ne.jp/freeze/install.html に書いてある手順に従ったものでした。その場合は、すこしばかり面倒な処理を要した。そのときは、初めてなので、事情がよくわからず、今思うと、新versionに古いversionの手順でinstallの処理を施したということになります。 このことに原因があるのか。 ということで、そのときにinstallしたものを削除し、 今回はxammpから改めてinstallしたわけですが、結果は同じでした。 もちろん、新versionに古いversionの手順でinstallの処理を施したことに原因があるのかどうか分かりませんが、ネットで色々と探ってみると、やはり installの仕方によっては不具合を経験したという書き込みもあることから、その可能性は排除できない。それと、二台持っているどちらのパソコンでも同じ現象が出ていることから、そのことの可能性を排除できない。 今回 前に installした php と apacheを削除して、xammpからinstallしたわけですが、それでも同じ現象が出ていることをどう説明するのか。 ということで、「新versionに古いversionの手順でinstallの処理を施したことに原因がある」という仮説でも そのような推定される原因を説明しきれない。 1) スクリプトには問題はない 2) installしたphp や apacheには問題はないだろう 3) あるとすれば、installの仕方か。しかし、xammpからのinstallでも同じ現象が起きている。 3) 使用している二つのパソコンにおいて 同じことが起きる 4) レンタルサーバーに例のスクリプトをuploadしても、同じことが起きる http://cgi.geocities.jp/autosu/test/p02.php かいもく見当がつきませんね。 それにしても、本当に貴重な書き込みありがとうございます。この書き込みを繰り返し読まさせていただいております。
- narusuji
- ベストアンサー率40% (4/10)
バイナリエディタで、欲しい文字列を欲しい文字コードで16進数に変換してから検索してみてはどうでしょうか。 (preg_matchはよく分からないのでmb_eregを使いました) 自信はありません。 $word="あいうえ'お"; if(mb_ereg("\x82\xA6\x27",$word,$match)){ //え'=82 A6 27 print "あるよ"; } else{ print "ないよ"; }
補足
narusujiさま ありがとうごさいます。 さっそく試してみました。 japan%27s とか、japan%5c%27s、あるいは if(mb_ereg("/japan's/", $word)) というように試してみました。 結果は、同じでした。 でも、アドバイスありがとうございました。
- dummyplug
- ベストアンサー率58% (134/230)
ANo.1でコメントを書いた者です。 それで、問題のif(preg_match()...の前の行に例えば echo "あなたが入力したのは「", $word, "」ですね。" という1行を入れるとどう表示されますか? ところで、、、 >そうですね、エスケープは関係ないですよね。 いえいえ、そういう問題であることもありますから実際に手を動かして試してみるのはとてもいいことです。今回はたまたま(たぶん)そういう原因ではないらしいというだけのことです。手を動かす、調べる、考える、のバランスを間違えなければOKです。
補足
dummyplugさま、たびたびありがとうございます。 さっそく 述べられていることをやってみました。結果は、 あなたが入力したのは「japan\'s」ですね。残念でした array(0) { } というものでした。 ただし、\の文字は、実際には スラッシュと なっています。/とは逆向きのスラッシュですね。 この個所に 自動的にこのようなエスケープ文字が置かれるんですね。なぜこうなるのか。 narusujiさま ありがとうごさいます。 さっそく試してみました。 japan%27s とか、japan%5c%27s というように試してみました。 結果は、同じでした。 でも、アドバイスありがとうございました。
- dummyplug
- ベストアンサー率58% (134/230)
"'"は「コンマ」ではなくて「アポストロフィー」または「シングルクォート」ですね。コンマ(またはカンマ)は","です。 それはそれとして、preg_match()ですけれど、 preg_match("/japan's/i", $word, $match)でうまくいくと思いますがだめですか?手元でちょろっと書いて試してみましたけれどうまくマッチするようですが…。うまくいかないとしたら$word変数の内容がどうなっているかとか、preg_match()関数の返値がいくつなのかとか教えてもらえますか。 あなたの整理を参照すると、1)がうまくいかないのが謎です。1)でいいはずなので、2)のようにエスケープする必要はないと思います。(してもマッチしましたけど。) 実行環境は何ですか?PHPのバージョンとかは関係あるかな? ところで、色々試してみて検討し、原因を推察しているのはすばらしいと思いました。が、今回はちょっとあらぬ方向に行っている感じもします…。あんまりその方向に走っちゃうと謎な独自法則を作っちゃうことがあるので気をつけてくださいね。
補足
早速のご返事ありがとうございます。前後のスクリプトを掲示させていただきます。 <html> <head><title></title> <meta http-equiv="content-type" content="text/html;charset=utf-8"> </head> <body> <form action="p02.php" method="post"> <input type="text" name="data4" size="5"><input type="submit" value="入力"> </form> <?php $word = $_POST['data4']; if(preg_match("/japan's/",$word,$match)){ $c03 = "正解です "; echo $c03; var_dump ($match);} else { $b = "残念でした "; echo $b; var_dump ($match); } ?> </body> </html> PHP Versionは、 5.2.6です。 var_dump ($match)の結果は、次の通りです。 array(0) { } > 今回はちょっとあらぬ方向に行っている感じもします たしかにそうなんですよね。 やはり 他の方々は preg_match("/japan's/",$word,$match) で問題なくヒットするということですから、 こうなるとわたしのブラウザやテキストエディタの設定に問題があるのかなと思ったりしてしまいます。 あるいは、encodingに問題があるのかと、いろいろと考えてしまいますね。 > 2)のようにエスケープする必要はないと思います そうですね、エスケープは関係ないですよね。
お礼
本当にありがとうございました。 magic-quotesに注目しなければ、今回の解決に至らなかったわけで、自分ひとりでは絶対にmagic-quotesのことに注目することはなかったでしょう。magic_quotes_gpcがonになっているかどうかを確認するコードを使ってやってみましたが、それではONになってました。 それと、このweb siteによると、PHPの6版では、 magic_quotesは削除されるんですね。 やはり、いろいと支障が出ているんでしょうかね。 返す返す、ありがとうございました。