• ベストアンサー

preg_match( '/^(\D+)(\d*)$/' , $変数 , $regs )

if( ! preg_match( '/^(\D+)(\d*)$/' , $変数1 , $regs ) ) { echo ( 'invalid dirname: ' . htmlspecialchars( $変数1 ) ); } $変数2 = $regs[2] === '' ? '' : intval( $regs[2] ) ; 正規表現だと思うのですが、どういう意味か教えてください。 □分からないなりに考えてみました… ▽1行目 $変数の内容が、'/^(\D+)(\d*)$/'にマッチしなければ、$regs へ代入。 ▽2行目 マッチしていた場合は、htmlspecialchars関数を実行した後、'invalid dirname: '+その結果を表示する。 ▽3行目 $regs配列変数の1番目を、何かして、$変数2 へ代入する。 ……誰か教えてください…。

  • re999
  • お礼率61% (476/777)
  • PHP
  • 回答数2
  • ありがとう数6

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

  • ベストアンサー
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

>どこら辺に問題ありそうでしょうか? まずpreg_matchで$regsを生成していますが、マッチしないケース すなわち「数字からはじまる文字列」の場合、$regsが未設定になります。 したがって$regs[2] === ''で評価すると$regsが未設定エラーになります。 またエラーレベルを下げた場合でも、$regs[2] === ''はfalseなので 数字ではない文字列をintvalで評価するため$変数2には0が代入されます。 やはりif分岐である程度場合分けをしっかりしてやらないといけないでしょう。 総じて$変数1に代入される文字列の想定を広げて、チェックしてやる必要があります。 また、仮にデータがきちんと通ったとして、$変数2は空文字か数字という データ型が確定しないフローになっています たしかにPHPは変数定義がいい加減ではありますが、あまりなんでも かんでも入れればいいというものではありませんので、ある程度 変数の型が一律になるような工夫が必要だとおもいます。

re999
質問者

お礼

丁寧に解説いただきまして、誠にありがとうございました。

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

▽1行目 パターン '/^(\D+)(\d*)$/'に $変数1 がマッチした内容を $regsに代入しています。 ただし、マッチしない場合は2行目の処理にうつります。 ▽2行目 変数1の内容をタグをエスケープして表示します。 ▽3行目 $reg[2]すなわち$変数の最初にあらわれる数字群をしらべ、 それがない場合は、$変数2に空文字を、そうでない場合は $変数2に文字を整数にキャストして代入します。 データチェック、フロー、データの持ち方にやや問題があるソースですね

re999
質問者

補足

回答ありがとうございます。 その後、自分でも調べていたのですが、大体こんな感じで合ってるでしょうか? 変数1が、 「先頭が非数字」または、「先頭が非数字でかつ最後が数字」以外のものだった場合には、変数1の内容をタグをエスケープして表示。但し、警告を表示するだけなので、いずれにせよ、回答いただいた内容の、3行目の処理は続行される。 >データチェック、フロー、データの持ち方にやや問題があるソースですね どこら辺に問題ありそうでしょうか? ご参考までにざっくりとでも教えていただけると、勉強になるのですが…。そもそも、何をやりたいのかはっきりしていない状況では、答えづらいかとは思いますが…

関連するQ&A

  • PHP:preg_match_allで複数条件指定

    preg_match_allで複数条件を設定する方法についてお尋ねします。 環境 PHP:5.1.6 MySQL:5.0.77 --------ソース例------------------------------------------ <a href="1000/23">1: 【国語】接続後について (授業1) (20)</a> <a href="1000/26">2: 【数学】分数 (206)</a> --------------------------------------------------------- 上記のようなHTMLソースを分解してMySQLに登録することを考えています。 (1行目) 1000/23 | 1 | 【国語】接続後について (授業1) | 20 (2行目) 1000/26 | 2 | 【数学】分数 | 206 という形に a hrefの中身 |スレッド番号 | タイトル | コメント数 4つに分解してMySQLに登録します。 正規表現を学んで、個別にデータを取り出すことはできました。 以下に作成したソースを記載します。 $contents='<a href="1000/23">1: 【国語】接続後について (授業1) (20)</a><a href="1000/26">2: 【数学】分数 (206)</a>'; preg_match_all( '/<a href="(.*?)">/su', $contents, $match ); foreach ( $match[ 1 ] as $var ) { echo htmlspecialchars($var)."<br>"; } preg_match_all( '/">([0-9]*?):/su', $contents, $match2 ); foreach ( $match2[ 1 ] as $var2 ) { echo htmlspecialchars($var2)."■<br>"; } preg_match_all( '/[0-9]: (.*?)\([0-9]*\)<\/a>/su', $contents, $match3 ); foreach ( $match3[ 1 ] as $var3 ) { echo htmlspecialchars($var3)."■<br>"; } preg_match_all( '/\(([0-9]*?)\)</su', $contents, $match4 ); foreach ( $match4[ 1 ] as $var4 ) { echo htmlspecialchars($var4)."●<br>"; } 【実行結果】 1000/23 1000/26 1 2 【国語】接続後について (授業1) 【数学】分数 20 206 1行ずつMySQLに登録したいので preg_match_all( '/条件1,条件2,条件3,条件4/su', $contents, $match ); のような形で指定して個々の値を下記の変数に入れることは可能でしょうか? ループ処理開始{ $url $num $title $res //MySQLに接続 //データ登録 }

    • ベストアンサー
    • PHP
  • preg_match・ereg_replaceの動作について

    preg_matchとereg_matchの動作について調べています。 下記のスクリプトを実行すると、$stringが「代入テスト」となります。 ------------------------------------------- $v_insert = "代入" $string = "{%v_insert}テスト"; while (preg_match("/\{%(.*)\}/U", $string, $match)){ $string = ereg_replace($match[0], $$match[1], $a_subject); } ------------------------------------------- $$match[1]→$($match[1])→$(v_insert)となり、 $match[0]→/\{%(.*)\}/U $match[1]→v_insert $$match[1]→代入 となるのは分かったんですが、なぜ、$match[0]→/\{%(.*)\}/Uで$match[1]がv_insertになるのかが分かりません。 このスクリプトはどのように動き、どのように変数に値が設定されているのでしょうか。

    • ベストアンサー
    • PHP
  • 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と定数について

    preg_matchと定数について $string = "○○ドメイン"; if (preg_match("/$string/", $_SERVER['SERVER_NAME'])) {  echo "○"; } else {  echo "✕"; とやると○になるのですが、 define("DOMAIN", "○○ドメイン"); if (preg_match("/DOMAIN/", $_SERVER['SERVER_NAME'])) {  echo "○"; } else {  echo "✕"; } とすると、✕になります。 なぜでしょうか?

    • ベストアンサー
    • PHP
  • スクリプトの中から使用されている変数と関数をリストする

    phpで書かれたスクリプトファイルの中から使用されている関数と変数をリストアップさせるようなことをしたいのですが、preg_matchを使うのが妥当でしょうか?また、正規表記はどんな感じがベストでしょうか?自分で試してみてもまったくへたくそでして... トホホ ぜひ皆さんの技量を拝見させてください ^^。 <?php $data = file_get_contents('~.php'); $functions = '/\s*\(*/i'; preg_match($functions, $data, $matches); print_r($matches); echo "<br>"; $variables = '/^\$[.+]/i'; preg_match($variables, $data, $matches2); print_r($matches2); echo "<br><br>"; echo $data; ?>

    • ベストアンサー
    • PHP
  • 【PHP】「ereg_match」はなぜ不人気なのか?

    PHP初心者です。 現在ファイルの中を英語や日本語で検索するプログラムを作っています。 検索といえば「preg_match」が一番人気あるように見えます。しかしたとえば、 mb_internal_encoding("UTF-8"); mb_regex_encoding("UTF-8"); if(preg_match( '/我輩は.である/' ,'我輩は猫である')){ print "マッチ!"; } 上記のような使い方をすると「.」は「猫」にマッチせず「...」にするとようやくマッチします。「preg_match」はマルチバイトに対応していないのでしょうか。 そこでマルチバイトと正規表現に対応した検索関数「mb_ereg_match」を知りました。 if(mb_ereg_match( '我輩は.である' ,'我輩は猫である')){ これなら正常にマッチします。 がしかし… 「mb_ereg_match」は全然辞書に載ってません。分厚いPHP辞書をいくつも持ってますが「ereg_match」すら載ってません。何か不人気の理由があるのでしょうか?気に入ったのに不安で使えません。 お詳しい方、解説よろしくお願いいたします。

    • 締切済み
    • PHP
  • 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
  • preg_replace_callback が渡す変数の扱い

    preg_replcace_callback を使用して、<a>タグ内のURLの字数を制御するコードに取り組んでいます。詳しい方アドバイスしてくださると助かります。 下のコードの、shorten(カスタム関数)に渡されるデータが配列なのですが、並列に並んだ配列のようなのです。echo をかけてみると、ArrayArray と表示されます。しかし、Array([0]=>Array [1]=>Array) ではないので、どうやって 処理をかけて return すればよいのか途方にくれています。 もしよい方法をご存知の方おられましたらどうぞよろしくお願いいたします。 <? $str = <<<HERE //長いURLのサンプルです。ここの掲示板の処理で途中で表示がカットされていますが、<a href="http://長いURL">http://長いURL</a>という構成になっています。 <a href="http://gooooooooooooooooooooooooooooooooooogle.co.jp">http://gooooooooooooooooooooooooooooooooooogle.co.jp[</a> <a href="http://yahooooooooooooooooooooooooooooooooooo.co.jp">http://yahooooooooooooooooooooooooooooooooooo.co.jp</a> HERE; $pattern = "#<a(.*?)>(.*?)<\/a>#s"; $str = preg_replace_callback($pattern, 'shorten', $str); echo $str; function shorten($matches) { foreach($matches as $index => $match) { if (strlen($match) > 20) { $matches[$index] = substr($match, 0, 20) . '....'; } } return $matches; } ?>

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

    <root>  <Space>    <Id>2075028953</Id>    <Depth>2</Depth>    <Title>コンテスト</Title>  </Space>  <Category>   <Count>2</Count>   <Item>     <Id>2075028959</Id>     <Title>グルメ、ドリンク</Title>   </Item>   <Item>     <Id>2075028966</Id>     <Title>音楽</Title>   </Item>  </Category>  <Site>   <Item>     <Id>2078063954</Id>     <Title>建築</Title>   </Item>  </Site> </root> のようなXMLで、preg_match_allで<category>タグの中の複数ある<item>要素のあらゆる要素を取得する正規表現を教えてください。 次の正規表現はどこが間違っていますでしょうか。 preg_match_all('@<Category>.*?(<Item>.*?<Id>(?P<id>.*?)</Id>.*?<Title>(?P<title>.*?)</Title>.*?</Item>).*?</Category>@s', $buf,$match,PREG_SET_ORDER); print_r($match); あるサンプル紹介サイトの真似をしただけでしたのでうまくいきませんでした。<category>タグ内の中身と、最初の<item>タグの中身しか取得できません。 だいたい.*?の処理の意味自体解っておりません。 恐縮ですが、よろしくお願いします。

    • ベストアンサー
    • PHP
  • 正規表現で切り出せません。 < と > の間?

    宜しくお願いいたします。 PHP5.1.6です。 メールの受信をするときにメールアドレスだけを切り出したいのですが うまく出来ません。 【例-1】の様に、すると < > の間が表示するのですが 【例-2】の例のように、変数を入れると何も表示しません。 【例-1】で使用した文字列は、【例-2】の$from を echo で表示させたものをコピーしています どのようにしたらいいでしょうか? 宜しくお願いいたします。 【例-1】 $test="教えてお名前 <****@*******.com>"; $pattern = "<(.*)>"; if (preg_match( "/".$pattern."/i", $test, $match ) ){ //$from0 = $match[0]; $from1 = $match[1]; //echo $from0; echo $from1; } これで、うまく echo $from1 でメールアドレスだけ表示してくれます。 *** なぜか、$from0 には元の文字列は表示しませんが。 置き換える元の文字列を下記変数に変えると表示しません。 【例-2】 $mboxes = imap_check($mbox); $head = imap_header($mbox, $i); $from = htmlspecialchars(mb_decode_mimeheader($head->fromaddress)); $pattern = "<(.*)>"; if (preg_match( "/".$pattern."/i", "$from", $match ) ){ //$from0 = $match[0]; $from1 = $match[1]; //echo $from0; echo $from1; } **$from の所は "" で囲んだり、外したりしましたが一緒でした。

    • ベストアンサー
    • PHP

専門家に質問してみよう