PHPのpreg_match_allで複数条件指定の方法とは?

このQ&Aのポイント
  • PHPのpreg_match_allを使用して複数条件を指定する方法について教えてください。
  • 具体的には、HTMLソースを分解してMySQLに登録する際に、aタグの中身を4つに分解する方法を知りたいです。
  • また、ループ処理を使用して一行ずつMySQLに登録する方法も教えてください。
回答を見る
  • ベストアンサー

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
  • 回答数1
  • ありがとう数3

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

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

こんな感じでどうでしょ? <?PHP $contents='<a href="1000/23">1: 【国語】接続後について (授業1) (20)</a><a href="1000/26">2: 【数学】分数 (206)</a>'; $pattern='/<a href="(.*?)">(\d)+:(.*?)\((\d+)\)<\/a>/mis'; if(preg_match_all($pattern , $contents, $matches,PREG_SET_ORDER )){ foreach($matches as $match){ $sql ="INSERT IGNORE INTO テーブル (`url`,`num`,`title`,`res`) VALUES("; $sql.= "'".mysql_real_escape_string($match[1])."'"; $sql.=",'".mysql_real_escape_string($match[2])."'"; $sql.=",'".mysql_real_escape_string($match[3])."'"; $sql.=",'".mysql_real_escape_string($match[4])."')";; print $sql."<br>\n"; } }; ?>

hpmt28
質問者

お礼

$pattern='/<a href="(.*?)">(\d)+:(.*?)\((\d+)\)<\/a>/mis'; の部分を自分で書き換えてみたところ希望通りの動作となりました。 ありがとうございました。

hpmt28
質問者

補足

yambejpさん。 回答ありがとうございます。 条件設定の()内が順番に配列に入るというやり方があるんですね。 勉強になります! 上記ソースを実行してみましたが 結果が INSERT IGNORE INTO テーブル (`url`,`num`,`title`,`res`) VALUES('','','','') INSERT IGNORE INTO テーブル (`url`,`num`,`title`,`res`) VALUES('','','','') という形でVALUESの部分に何も表示されません。 お手数ですがもう一度ソースの確認お願いできますでしょうか? あと、 $pattern='/<a href="(.*?)">(\d)+:(.*?)\((\d+)\)<\/a>/mis'; の最後のmisの意味ですが、 m →文字列を複数行として扱う。 i →大文字と小文字を区別しない。 s →文字列を単一行として扱う。 という個々の意味はわかるのですが、 mとsを記載するということは 「文字列を複数行として扱う。」「文字列を単一行として扱う。」となり、文字列を「単一行としても複数行としても扱う」という理解でよろしいのでしょうか? misをsimと順序を入れ替えると結果が変わったりするものなのでしょうか?

関連するQ&A

  • 正規表現 preg_match_all 

    $c = preg_match_all('@href="/Top/World/Japanese/(?P<query>.*?)">(?:<b>|)(?P<cate>.*?)(?:</b>|)</a>@s', $buf,$match,PREG_SET_ORDER); print_r($match); の(?:<b>|)と(?:</b>|)の部分がまちがっているので、<b></b>タグがあってもなくてもいい場合にマッチさせることができないと思っています。 どうか教えてくださいませ。 ちなみにPHPの5.2.2です。

    • ベストアンサー
    • PHP
  • preg_match_allで取得データをDBへ

    質問:preg_match_allで取得したデータをDBへ格納したいです。 記述文 $pattern = "|HREF=.*?\>|"; preg_match_all($pattern,$str,$match); 補足: $pattern で指定範囲を書いてます。 $str には $patternでとってくる参照データ先が入ってきます。 print_r($match); で念のためブラウザに吐き出すと Array ( [0] => Array ( [0] => HREF="AAA"> [1] => HREF="../../../../Top"> 以下省略 取得したい範囲が取れていることは確認できました。 目的は、とってきた [0] => HREF="AAA"> [1] => HREF="../../../../Top"> : =>より先の文字列が、DBの1つのレコードに1つずつ入っていくイメージです。 アドバイスよろしくお願いします。

    • ベストアンサー
    • PHP
  • preg_match_all 複数の文字列を取得

    preg_match_all で複数の文字列を取得したい。 正規表現について勉強している者です。 preg_match_allを使って複数の文字列を取得したいのですが、 パターンの書き方に苦戦しています。 取得したいデータは以下の5つです。 一つずつであれば、どのデータも問題なく取得できますが、 2つ以上組み合わせると、抽出した結果に余計な文字が入ったり、 何も結果を返さなかったりとなってしまいます。 皆様お知恵を貸してください。よろしくおねがいします。 ///////////取得したいデータ/////////// 1つめ→○△□○△□○日本語や英語や数字△□○△□○△□○△□ 2つめ→2010/03/04(日) 16:33:48.21 3つめ→Reg1046H2556USAsantaclala 4つめ→score995 5つめ→●▲■<br> ●▲■●日本語や英語や数字▲■●▲■●<br> ▲■●▲■●▲■●▲■●<br> ▲■●▲■●▲■ 5つめには改行が入ることもあります。 /////////////////////////////////////// HTMLコード↓ <div class="cell" material="\1"></div></div> : <span style="grey"><b>○△□○△□○△□○△□○△□○△□</span></b> DATE 2010/03/04(日) 16:33:48.21 <div class="gj"><a href="www.hoge.com" class="Reg1046H2556USAsantaclala"><span class="well">domestic</span></a><div class="hollywater" name="BUFFALO"></div></div>bridge</div><div id="score995">●▲■<br> ●▲■●▲■●▲■●<br> ▲■●▲■●▲■●▲■●<br> ▲■●▲■●▲■</div>

    • 締切済み
    • PHP
  • 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 へ代入する。 ……誰か教えてください…。

    • ベストアンサー
    • PHP
  • htmlソースからアンカータグ内のURLを配列に

    お世話になっております。 file_get_contents()で取得したhtmlファイルのソースにある、アンカータグに設置されている、URLおよび、そのアンカータグに囲まれたテキストを取得して配列に収めたいと考えているのですが、いろいろと調べていても、思うような結果を出せずにいる状況です。 あるサイトにて、以下のようなソースがあり、これをヒントとしているものの、初めて目にする配列の中の配列?に戸惑い、その分解の仕方が分からず、またアンカータグ内に、target="_blank"などの記述があったりすると、配列に収めることが出来なかったりで、対処の仕方がwからずにいる状況です。 $html = ' <ul> <li><a href="http://www.yahoo.co.jp/">Yahoo!JAPAN</a></li> <li><a href="http://jp.msn.com/">MSN</a></li> <li><a href="http://www.google.co.jp/">Google</a></li> </ul> '; $pattern = '/<a href="([^"]+)">(.+?)<\/a>/is'; $match = array(); preg_match_all($pattern, $html, $match, PREG_SET_ORDER); var_export($match); echo "<br><br>"; print_r($match); 知識が乏しく、お恥ずかしいところと思うことろではありますが、アドバイスなど頂戴できれば幸いです。 お忙しいなか恐縮ですが、宜しくお願い申し上げます。

    • ベストアンサー
    • 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
  • 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
  • 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
  • preg_match_allによる文字列切り出しについて

    preg_match_allによる文字列切り出しについて 宜しくお願い致します。 $data[0] = "あいうえおかきくけこ2011年2月3日さしすせそ"; $data[1] = "あいうえおかきくけこ2014/5/6さしすせそ"; $data[2] = "あいうえおかきくけこ2017-8-9さしすせそ"; $data[3] = "あいうえおかきくけこ2010.11.12さしすせそ"; $data[4] = "あいうえおかきくけこ13時-14時さしすせそ"; というデータから日付だけを抽出し、切った場所で配列に収めたいと考えております。 自分なりに考えたパターンは、 for($x = 0; $x < count($data); $x++) { preg_match_all("/\\d{4}[\-\/\.|年]|\\d{1,2}[\-\/\.|月]|\\d{1,2}/u",$data[$x],$data_array); print $data_array[0][0]; print $data_array[0][1]; print $data_array[0][2]; print "<br>"; } これを実行すると、下記の出力になってしまいます。 2011年2月3 2014/5/6 2017-8-9 2010.11.12 1314 ファイルの文字コードは「UTF-8」です。 最後の「1314」は$data[4]の「13時-14時」の部分が切り出されてしまい、ここは無視して欲しいのです。 この部分で数時間悩んでおり、いい加減、気持ち悪くなってきました。 またまたお願いで大変申し訳ないのですが、どなたか助けてくださいー ( iдi )

    • ベストアンサー
    • PHP
  • preg_match_all関数でaタグの属性を

    PHPのpreg_match_all関数でaタグの属性hrefの値だけをすべて取得するにはどうしたらよいでしょう?? 正規表現の部分が分かりません。 お願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう