• ベストアンサー

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にとって特別な意味を持つ文字列に変わるのではないか。

  • PHP
  • 回答数6
  • ありがとう数18

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

  • ベストアンサー
  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.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の状況を含め、色々な設定がどういう状況になっているかを確認しておくのもよいでしょう。

tonbeisan
質問者

お礼

本当にありがとうございました。 magic-quotesに注目しなければ、今回の解決に至らなかったわけで、自分ひとりでは絶対にmagic-quotesのことに注目することはなかったでしょう。magic_quotes_gpcがonになっているかどうかを確認するコードを使ってやってみましたが、それではONになってました。 それと、このweb siteによると、PHPの6版では、 magic_quotesは削除されるんですね。 やはり、いろいと支障が出ているんでしょうかね。 返す返す、ありがとうございました。

その他の回答 (5)

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.5

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)まわりではないかと考えているのですが…。

tonbeisan
質問者

お礼

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); } ?>

tonbeisan
質問者

補足

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)
回答No.4

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()で使っている正規表現には問題なさそうです。問題は、「入力された文字列に余計な"\"が入ってしまう」ことにあります。 こちらを追ってみてください。

tonbeisan
質問者

補足

なんども貴重な情報、ヒント、アドバイスありがとうございます。 深いですね。書かれていることが。  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)
回答No.3

バイナリエディタで、欲しい文字列を欲しい文字コードで16進数に変換してから検索してみてはどうでしょうか。 (preg_matchはよく分からないのでmb_eregを使いました) 自信はありません。 $word="あいうえ'お"; if(mb_ereg("\x82\xA6\x27",$word,$match)){ //え'=82 A6 27 print "あるよ"; } else{ print "ないよ"; }

tonbeisan
質問者

補足

narusujiさま ありがとうごさいます。 さっそく試してみました。 japan%27s とか、japan%5c%27s、あるいは if(mb_ereg("/&#x6a;&#x61;&#x70;&#x61;&#x6e;&#x27;&#x73;/", $word))   というように試してみました。 結果は、同じでした。 でも、アドバイスありがとうございました。

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.2

ANo.1でコメントを書いた者です。 それで、問題のif(preg_match()...の前の行に例えば echo "あなたが入力したのは「", $word, "」ですね。" という1行を入れるとどう表示されますか? ところで、、、 >そうですね、エスケープは関係ないですよね。 いえいえ、そういう問題であることもありますから実際に手を動かして試してみるのはとてもいいことです。今回はたまたま(たぶん)そういう原因ではないらしいというだけのことです。手を動かす、調べる、考える、のバランスを間違えなければOKです。

tonbeisan
質問者

補足

dummyplugさま、たびたびありがとうございます。 さっそく 述べられていることをやってみました。結果は、 あなたが入力したのは「japan\'s」ですね。残念でした array(0) { } というものでした。 ただし、\の文字は、実際には スラッシュと なっています。/とは逆向きのスラッシュですね。 この個所に 自動的にこのようなエスケープ文字が置かれるんですね。なぜこうなるのか。 narusujiさま ありがとうごさいます。 さっそく試してみました。 japan%27s とか、japan%5c%27s というように試してみました。 結果は、同じでした。 でも、アドバイスありがとうございました。

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.1

"'"は「コンマ」ではなくて「アポストロフィー」または「シングルクォート」ですね。コンマ(またはカンマ)は","です。 それはそれとして、preg_match()ですけれど、 preg_match("/japan's/i", $word, $match)でうまくいくと思いますがだめですか?手元でちょろっと書いて試してみましたけれどうまくマッチするようですが…。うまくいかないとしたら$word変数の内容がどうなっているかとか、preg_match()関数の返値がいくつなのかとか教えてもらえますか。 あなたの整理を参照すると、1)がうまくいかないのが謎です。1)でいいはずなので、2)のようにエスケープする必要はないと思います。(してもマッチしましたけど。) 実行環境は何ですか?PHPのバージョンとかは関係あるかな? ところで、色々試してみて検討し、原因を推察しているのはすばらしいと思いました。が、今回はちょっとあらぬ方向に行っている感じもします…。あんまりその方向に走っちゃうと謎な独自法則を作っちゃうことがあるので気をつけてくださいね。

tonbeisan
質問者

補足

早速のご返事ありがとうございます。前後のスクリプトを掲示させていただきます。 <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)のようにエスケープする必要はないと思います そうですね、エスケープは関係ないですよね。

関連するQ&A

  • PHPの正規表現「preg_match」で漢字を含む場合のマッチパター

    PHPの正規表現「preg_match」で漢字を含む場合のマッチパターンについて 宜しくお願い致します。 preg_matchを使っての正規表現で、「あいうえおかきくけこ3月10日さしすせそ」という文字列から「3月10日」だけを抽出するには、どういうパターンが良いのでしょうか? 下記の様にやってみましたが、だめでした。。。 preg_match("/\d{1,2}[月]\d{1,2}[日]/",$hoge,$match) これではうまくいきません。 どなたかお助けくださいー!

    • ベストアンサー
    • PHP
  • preg_matchの正規表現がうまくいかない

    たとえば、http://gehasoku.com/?p=2のソースコードには ------------------- <rdf:Description rdf:about="http://www.com/aaa.html" trackback:ping="http://www.com" dc:title="タイトル" dc:identifier="http://iii.com/bbb.html" dc:subject="ハードウェア" dc:description="1 名前:名無しさん " dc:creator="soft_net" dc:date="2012-02-21T20:05:01+09:00" /> ------------------- のような形の<rdf:Description~~~/>タグの情報ががいくつかあると思います。これらすべてを文字列として取得したくて、次のようなphpを作成しましたが、うまく動作しません。 原因はどうやらpreg_match_allの正規表現がうまくいっていないからのようですので、 <rdf:Description~~~/>を抜き出すことができる正規表現を教えてください。 自分でもここでチェックしながらやりましたが、 http://www.rider-n.sakura.ne.jp/regexp/regexp.php <rdf:Description~をマッチすることはできても、/>で閉じることができませんでした。 よろしくお願いします。 <?php $url="http://gehasoku.com/?p=2"; $html=file_get_contents($urls); preg_match_all("/<rdf:Description(.*)?\/>/",$html,$match); print_r($match); foreach($match[1] as $value){ echo $value; } ?>

    • ベストアンサー
    • PHP
  • PHP preg_match_all関数の配列をMysqlに格納したい

    PHP preg_match_all関数の配列をMysqlに格納したい PHP初心者です。 preg_march_all関数を使って正規表現でマッチングする練習を行っています。 preg_march_allを使った場合、マッチングした結果が多次元配列となって出力されると思うのですが、それらをそれぞれのレコードに分けてMysqlに格納したいと思っています。 php入門サイトのものを弄って作ったのですが、 while (! feof($fp)) { $s = fgets($fp); $n = preg_match_all($Pattern, $s, $ar, PREG_SET_ORDER); for ($i = 0; $i < $n; $i++) mysql_query("insert into seikihyougen1 (benri) value ('$ar[$i][2]')"); } 結果はマッチングした数のレコード分、benriカラムにArray[2]という文字列が入力されてしまいます。 これらをマッチングした文字列に直してMysqlに入れるにはどうすればよいのでしょうか?

    • ベストアンサー
    • PHP
  • カンマ区切りの数字で指定したものだけを取り出したいです。

    カンマ区切りの数字で指定したものだけを取り出したいです。 $test = "1,2,3,5,10,11,14" という文字列から、1だけを取り出したい場合、どうしたらよいのでしょうか。 preg_match_all("/(?<!1)1(?!1)/",$test,$match); print implode($match[0]); としてますが、なぜか10,11,14と1が含まれるもの全てが表示されてしまいます。

    • ベストアンサー
    • PHP
  • 、"(ダブルクォーテーション)で囲まれている文字列を正規表現で取得

    質問させてください。 abcdef -s "xsalkjsdflsd#$%_asdasdlasdlakjsd&=Daskdjh" asdakjsd のような文字列があります。 これの、"(ダブルクォーテーション)で囲まれている文字列を取得したいのですが、正規表現がうまくいきません。 取得結果としてはは、xsalkjsdflsd#$%_asdasdlasdlakjsd&=Daskdjh の部分がほしいです。 preg_match('/"([.*])"/', $str, $matches);とやったり preg_match('/\"([.*])\"/', $str, $matches);とやったり preg_match('/\"([.*?])\"/', $str, $matches);とやったりしたのですが、 どうしても$matchesにほしい結果は入っていません。 どのような正規表現で取得可能でしょうか? 何卒ご教授ください。

    • ベストアンサー
    • PHP
  • エスケープ文字そのものにマッチさせる正規表現

     お世話になっております。  PHPの正規表現でエスケープ文字\そのものにマッチさせる正規表現がなかなか作れません。Perl互換のpreg_replaceなども試してみましたがダメでした。エスケープ文字そのものを削除したいのですが、どうしたらよいでしょうか? $value = ereg_replace ('\\', '', $value);//ダメでした。 $value = preg_replace ('/\\/', '', $value);//同様にダメでした。 $value = preg_replace ('/[\\]/', '', $value);//同様にダメでした。  文字列中に\が入っていたり、単独で\があった場合は必要ないので削除するといった感じです。 $value = ereg_replace ('[][}}{)(!"#$%&\\~|*+,/\^\'<>`;:?\\=]', '', $value); これでいけるかと思ったのですが、\だけ残ってしまいます。最後辺りの\\で\文字それ自体にマッチするかと思うんですが…。 わかる方がいらしたらおしえてください。よろしくお願いします。

    • ベストアンサー
    • PHP
  • 正規表現preg_match('#^(?:[a-z

    preg_match('#^(?:[a-z0-9\-]+\.){1,}[a-z]{2,}$#i', $hoge)の意味を教えて ・#iなので、デリミタは#。大文字小文字は無視 ・先頭に、【「:(英数字ハイフンが1回以上).」が、0回または1回の出現】が1回以上の繰り返し ・続いて、英字が2回以上の繰り返し と思い、 :123a-.ss てやってみたのですが、0が返ってきました。 この正規表現の意味と、 この場合、どんな文字列が当てはまるか知りたいです

    • ベストアンサー
    • PHP
  • preg_matchの検索について

    <?php  header("content-type: text/plain");  $pat = '/<a href="([^"]*)">/';  $html="<p><a href=\"http://test.net/test3.html\">リンク</a></p>";  preg_match($pat,$html,$match); print_r($match); ?> 上記正規表現プログラムを作成しました。 結果を確認したところ、 Array ( [0] => <a href="http://test.net/test3.html"> [1] => http://test.net/test3.html ) このようにでるのですが、[1]つめが存在している理由がわかりません。 [0]だけが出てくると思っていたのですが、なぜ、[1]はどのような理由で作成されたのでしょうか。 ご教授よろしくお願いします。

    • ベストアンサー
    • PHP
  • preg_matchの正規表現で

    空白があってもなくてもマッチするようにするにはどうやって表現したらよいでしょうか。 マッチ条件:"佐藤ヨシオ" 対象:"佐藤 ヨシオ","佐藤ヨシオ","佐藤ヨ シオ"; これらすべてにマッチするようにしたいです。 x:拡張正規表現(空白が無効) と他サイトで見かけたのですが、これをどうやって使えばいいのかわかりません。 preg_match("佐藤ヨシオ",$val); このようにやってみてもうまく動いてくれません。 ヒントでもいいので教えていただけたらと思います。

    • 締切済み
    • PHP
  • \bとはなんでしょうか?

    今、正規表現を勉強中です。 preg_match( "/\bweb\b/" , $str ) というのが出てくるのですが、この「\b」とはなんでしょうか? この文字列の問題だとも思うのですが検索しましたが、それらしいものはヒットしませんでした。 ご存知の方、書き込みをください。 よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう