preg_match_allによる文字列切り出しの方法と注意点

このQ&Aのポイント
  • preg_match_allを使った文字列切り出しの方法についてご質問いただきました。
  • 質問にあるコードを使って、データから日付を抽出し、配列に収める方法を説明します。
  • ただし、注意点として、一部のデータについては正しく切り出せない可能性があるので、修正が必要です。
回答を見る
  • ベストアンサー

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 )

  • nikuq
  • お礼率75% (477/631)
  • PHP
  • 回答数1
  • ありがとう数5

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

  • ベストアンサー
  • smileeeen
  • ベストアンサー率70% (21/30)
回答No.1

「1314」という文字列が出力されてしまう原因ですが、 正規表現の中に不必要な「|」が存在しているためです。 「|」は「OR」と同じような意味合いで、 その前後に書かれたどちらかのパターンにマッチするものを探索します。 これが正規表現内で「年」「月」「日」を表わそうとしている それぞれのパターンの間に挟まってしまっているため 「13時-14時」の数字部分が「日」を表わそうとしている \d{1,2} にマッチするためこのような出力となります。 また、[ ]はその中に書かれた文字のいずれかにマッチするもの という意味なので、[ ]内に「|」の記述は不要です。 マッチした結果を「年」「月」「日」で分ける必要がないのであれば 下記のような形でいかがでしょうか。 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 "<br />"; }

nikuq
質問者

お礼

ありがとうございます! お礼が遅くなりました。 頂いた情報を元に、プログラムに当てはめたら期待通りの結果になりました! 本当にたすかりましたー!

関連するQ&A

  • 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
  • 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_allのバグ?

    改めて質問させていただきます。 <textarea cols=36 rows=15 name="before" wrap="virtual" style="width:320px;height:250px;">方法</textarea> <textarea cols=36 rows=15 name="after" wrap="virtual" style="width:320px;height:250px;">Method </textarea> これを preg_match_allの'/<textarea.*>(.*)<\/textarea>/ms'で二つとも取得するのですが、 他に色々と長い文字列を打ったうえで上記を取得すると何も表示されません。 ちなみに、文字の長さが半角で2820文字以上になると表示されません。 2819未満だとちゃんと取得して表示してくれます。 preg_match_allの関数のマニュアルを見たところそのような仕様は書いてありませんでした。 何かこれを取得できるように解決する方法はありませんでしょうか?

    • 締切済み
    • PHP
  • 正規表現 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、余計な文字を消したい

    $source = "(・・・数千文字あるので省略します)" $data = '/<td class="c">\s*.*\s*<\/td>|<td>.*<\/td>/'; preg_match_all($data, $source, $data_matches); var_dump($data_matches); 上記、var_dumpの出力内容は(何故か二次元配列になってしまうんですが)、 array(1) { [0]=> array(80) { [0]=> string(72) "<td class="c"> hogehoge </td>" [1]=> string(21) "<td class="c">hogehoge</td>" [2]=> string(27) "<td>hogehoge</td>" [3]=> string(9) "<td>hogehoge</td>" [4]=> string(21) "<td class="c">hogehoge</td>" [5]=> string(9) "<td>hogehoge</td>" 上記の様に、欲しかったhogehogeの情報は取れているんですが、 <td class="c"></td>、<td></td>が邪魔です。。。 '/<td class="c">\s*.*\s*<\/td>|<td>.*<\/td>/'; 上記の正規表現は、hogehogeの場所を突き止めるのに必要だと思うんですが、 hogehogeのみ抽出したくて・・・。 $re = str_replace('<td class="c">', "", $data_matches); var_dump($re); 例えば上記の様にしても、<td class="c">が消えてくれません。。。 質問 1、何故、二次元配列になってしまうんでしょうか?問題ないのでしょうか?出来れば普通の配列にしたいんですが・・・。 2、どうすればhogehogeの場所を突き止め、そしてさらにhogehogeのみの情報を抽出出来るでしょうか?

    • 締切済み
    • 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
  • 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の 正規表現

    <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初心者です。 今、文字列$strに使われている文字をチェックして、エラーのときはその文字を表示させたいと思っています。 文字列 $strに特定の文字(B,Z,J,O,X,*)が入っていたらエラーで、エラーになった文字を表示させたいと思っています。このとき、使用する関数はpreg_match_allでいいのでしょうか。 今は、下記のように書いています。 if(preg_match_all("/[B,Z,J,O,X,*]/i",$aaseq[$i],$moji[$i])){     ほかに適当な関数あるでしょうか。

    • ベストアンサー
    • PHP
  • textより$$にはさまれた文字列を取得する方法

    初めて質問させていただきます。 windowsにて、phpプログラムでtxt形式の文より$$で囲まれた文字列を抽出したいのですが上手くいきません。 サンプルとして現在使用している文は以下の通りです。 電圧に関するオームの法則は $$V=RI$$ である。 抵抗に関するオームの法則は $$R=V/I$$ である。 電流に関するオームの法則は $$I=V/R$$ である。 作成したプログラムは以下の通りです。 <?php $in = "C:/equation.txt"; $fp = fopen("$in","r"); while(!feof($fp)){ $data = fgets($fp,1024); print $data; } $patttern = "\$\$(.*)\$\$"; preg_match_all("/".$patttern."/",$data,$array); $value_list = array_values($array); foreach($value_list as $key => $value){ print $key.") ".$value."\n"; } 現状ではテキストは正常に返ってくるのですが、配列がちゃんと帰ってきません。おそらくpreg_match_allの時点で上手く抽出出来ていないと思うのですが何がおかしいのか分かりません。 どなたかご指導のほどよろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう