[PR]ネットとスマホ まとめておトク!

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に接続
//データ登録
}

A 回答 (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";
}
};
?>

この回答への補足

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と順序を入れ替えると結果が変わったりするものなのでしょうか?

補足日時:2011/11/22 20:00
    • good
    • 0
この回答へのお礼

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

ありがとうございました。

お礼日時:2011/11/26 19:58

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qpreg_match関数で正規表現の複数指定方法。

./aaaディレクトリ内においてファイル名に、『bbbb』及び『cccc』と言う文字列が含まれるファイルを./eeeディレクトリに移動させるスクリプトを考えております。

以下は『bbbb』のみを拾うようなスクリプトです。
=========
<?PHP
if ($dir = opendir("./aaa")) {
while (($file = readdir($dir)) !== false) {
if(preg_match("/bbbb/",$file)) rename("./aaa/".$file,"./eee/".$file);
}
closedir($dir);
}
?>
=========
上記は前にこちらで質問させていただき、正常に動くことを確認しております。
今回は『bbbb』及び『cccc』が含まれる場合に./eeeディレクトリに移動させることを考えております。
このような場合は『cccc』はどのよう記載すればよいのでしょうか?ご教授の程よろしくお願いいたします。

Aベストアンサー

どちらとも含まれる場合と言う意味ですよね?

単に preg_match をもう一回やればいいのではないかと。

if(preg_match("/bbbb/",$file)) {
if(preg_match("/cccc/",$file)) {
rename("./aaa/".$file,"./eee/".$file);
}
}

Q文字列から、特定の文字を削除したい

アンケートで入力された値を受け取り、メールで送信しているのですが、受け取った値から、特定の文字列を削除することは可能でしょうか?

例えば電話番号の入力の場合、
03-xxxx-xxxx →03xxxxxxxx
077-xxx-xxxx →077xxxxxxx
のように、-(ハイフン)が入力されていたら、-を削除した文字列に置換してメール送信したいのです。
入力する時に、3つのテキストエリアに分けるのは諸事情でできないので、特定の文字を削除する関数か処理方法がありましたら、教えていただきたいです。
よろしくお願いします。

Aベストアンサー

str_replace
http://itbtech.itboost.co.jp/man/php_man/function.str-replace.html

<?php
$orig_telno = "03-xxxx-xxxx";

$telno = str_replace("-", "", $orig_telno);
echo $telno;

03xxxxxxxx

“PHP 文字列” あたりをキーワードに検索すれば
そんなに難しいものでもないような。

QPHPでタグ内からURLと文字を抜き出したい

PHP4.3で
$html_tag = '<a href="http://www.hogehoge.com/hogehoge/hoge/sample.html" class="hogehoge" title="hogehoge">りんく先名称</a>';
というような変数から
「http://www.hogehoge.com/hogehoge/hoge/sample.html」
のURLと
「りんく先名称」という<a>で囲まれた文字列を抜き出したいのです。

preg_matchを使っていろいろやってみたのですが、どうもうまくいきません。というか、正規表現がどのように書いていいのかわからないのですが・・・
そもそもpreg_matchを使わずとも簡単な方法があるのでしょうか?

大変恐れ入りますが、ご教授いただけませんでしょうか?

Aベストアンサー

この例をもとにして思いっきりはしょって書くと

<?
$html_tag = '<a href="http://www.hogehoge.com/hogehoge/hoge/sample.html" class="hogehoge" title="hogehoge">りんく先名称</a>';
preg_match("|<a href=\"(.*?)\".*?>(.*?)</a>|mis",$html_tag,$matches);
$url=$matches[1];
$text=$matches[2];
?>

Q正規表現で複数行に渡る範囲を取り出す

<html>

<div></div>

<div class="content">
<b>内容<b/><br />
<img src="#" />
<p>ほげほげほげほげ</p>
</div>

<div></div>

</html>

上のようなHTMLがあるとします。<div>の前後にもhtmlは書かれています。
そこから正規表現で<div class="content">~~~</div>の中身を取り出したいのですが、できません。
言語はPHPで、

/<div class=\"content\">.*<\/div>/
と書いてみたんですが、改行などがありうまくいきませんでした。

どのようにに記述すればうまくいくんでしょうか。

Aベストアンサー

> preg_match(/<div class=\"content\">.*<\/div>/s),$target);
> と書いて、divの中身を取り出すことはできたのですが、
> <div class="content">の対の</div>ではなく、html文中にある一番最後の</div>が対象になってしまいました。
* だと最長一致なので
代わりに最短一致の *? を使ってみてはどうでしょう。

(/<div class=\"content\">.*?<\/div>/s

Qsyntax error, unexpected '}' というエラーの対処法

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" maxlength="3" />
<input type="sbumit" value=回答" />
</form>
<hr />
<?php
session_start();
if(is_null($_SESSION['answer'])){
mt_stand(microtime()*1000000);
$_SESSION['answer']=mt_rand(1,100);
$_SESSION['game_cnt']=0;
}
if($_POST['answer']!=""){
$_SESSION['game_cnt']++;
if($_session['answer']==$_POST['answer']){
print("おめでとうございます".
$_SESSION['game_cnt']."回で正解しました!");
session_destroy();
}else{
if($_SESSION['answer']>$_POST['answer']){
print("もう少し大きいです。");
}else
print("もう少し小さいです。");
}
}
}
?>
</body>
</html>
それとこの間違えたところをなおしたあとはいつもコンピュータを再起動しないと修正したところが適用されないのですがほかに方法はないですか?基本的な質問ですいません。

PHPを習い始めて三日目になるのですがParse error: syntax error, unexpected '}' in C:\Program Files\Apache Group\Apache2\htdocs\****\****\game.php on line 33
というエラーがでるのですが33行目前後のどこをなおせばいいのでしょうか?
・game.php
<html>
<head>
<title>数当てゲーム</title>
</head>
<body>
<h1 style="background:#cccccc">数当てゲーム</h1>
<form method="POST" action="game.php">
1~100までの数を入力してください
<input type="text" name="answer" size="5" max...続きを読む

Aベストアンサー

print("もう少し大きいです。");
}else
print("もう少し小さいです。");
のelseの後に{がないようですが、大丈夫でしょうか?

QParse error: syntax error, unexpected T_STRING in・・・118と出るのですが

Parse error: syntax error, unexpected T_STRING in 。。。 on line 118
とでるのですが対処はどうすればよろしいでしょうか?

Aベストアンサー

118行目をみてみてください。
ダブルクォーテーションのなかでダブルクォーテーションを使ったり
してませんか?
基本的な文法ミスなので、自己解決できないと今後きびしいですよ。

QボタンをクリックでPHP文を実行

ボタンをクリックしたときのみPHP文を実行したいのですが・・・

<input type="button" onClink="<?php~?>">
でいけるかと思ったのですが、
ページ表示時に<?php~?>が実行されてしまい、うまくいきませんでした。

onClink="window.open(test.php)"
という方法以外でお願いします。

Aベストアンサー

AjaxはもともとJavaScriptの機能である非同期通信をつかったもので。Ajaxという言語があるわけではありません

Ajaxを利用するのであれば、JavaScriptのXMLHttpRequestを使って非同期通信できるような実装をしなくてはなりません
簡単にサンプルコードで書けるほど単純なものでもありません

一般的なサーバーサイドスクリプトの動作として、
ボタンを押す->サーバーへリクエストする->サーバーが処理する->クライアントに何かしらの結果を返す(出力する)です
つまり、PHP等のサーバーサイドスクリプトは、遷移させることが大前提で動作します

ですから、ボタンを押してその場でJavaScriptと同じようにPHPが動くなんてことはありえません。
ボタンを押したらサーバーにリクエストする という動作ならば可能です。

つまり
質問で言われているような
onClink="window.open(test.php)"

<form name="f1" action="test.php" method="post">
<input type="submit" name="submit" value="submit" />
</form>
等のような形になります

こういった一般的な方法だと いちいち画面が切り替わったようになってしまうのを嫌って Ajaxでコレと同じことを、画面を切り替えずに行っているだけに過ぎません

AjaxはもともとJavaScriptの機能である非同期通信をつかったもので。Ajaxという言語があるわけではありません

Ajaxを利用するのであれば、JavaScriptのXMLHttpRequestを使って非同期通信できるような実装をしなくてはなりません
簡単にサンプルコードで書けるほど単純なものでもありません

一般的なサーバーサイドスクリプトの動作として、
ボタンを押す->サーバーへリクエストする->サーバーが処理する->クライアントに何かしらの結果を返す(出力する)です
つまり、PHP等のサーバーサイドスクリプトは、...続きを読む

Qforeachで回った数を表示したい

単純な質問ですみません。
====
//getTestlistは別ファイルで定義済み。
<?
$testlist=getTestlist();
foreach($testlist as $test){
?>


<? } ?>
====
例えば↑こんなふうにforeachで$testlistが存在するだけ回したとします。
そのときに何回まわったか?($testが何件あったか?)だけを表示したいのですが、そんなことってできますか?
表示したい位置は<? } ?>の外側にと考えています。
あさってな質問でしたらすみません。
phpVer 4.3

よろしくお願いいたします。

Aベストアンサー

<?
$testlist=getTestlist();
$n=0;
foreach($testlist as $test){
$n++;
?>
<?}?>

<?=$n?>回
とかでよいかと思います。

途中でbreakなどが無ければ
<? echo count($testlist) ?>でも良いかも知れません。

QPHPのif文でその処理を途中で抜けるにはどうすればよいでしょうか?

PHPのif文でその処理を途中で抜けるにはどうすればよいでしょうか?
for文やwhile文ではbreakやcontinueなどが使えるようですが、if文にはないのでしょうか?

条件分岐がいくつかあって、その一つを途中で抜けて次の条件分岐へと移行したいのですが、
exitを使ってしまうと、次へ行かずに処理が中止されてしまいますし、
どのようにすればよいのか分からず困っています。何かよい方法はないでしょうか?

Aベストアンサー

例えば「goto 演算子」を使うとかですね。
http://php.net/manual/ja/control-structures.goto.php
(参考URL)

「if文を強制終了」というより「ステップの強制移動」と言った感じです。

ただ、あまりgoto演算子はお勧めできません。
複雑な処理になればなるほど、バグが発生した際にバグ元を発見し難くなります。

本来は細かく制御文を入れていけば、あまり必要ないと思いますが・・・

QPHPで変数から1行目だけを取得したい

変数に格納されたデータの1行目のaaaだけを取り出す方法を教えてください。

※データはWEBサイトのURLリストで常に変動します。

複数行のデータ(\n区切り)
例) aaa
  bbb
  ccc

又は1行の半角カンマや半角スペースなどの文字で区切られたデータ
例) aaa, bbb,ccc,
   aaa bbb ccc

上記のどちらかの形式で変数$dataに格納が可能です。

この$dataに格納されたaaaだけを取得するにはどうしたらいいのでしょうか?

PHP初心者のためプログラムソースを書いていただけると助かります。

Aベストアンサー

半角スペースか、カンマか、改行マークでわけられた1つ目のデータで
あれば、こんな感じですね。


<?PHP
$str1="aaa
bbb
ccc";
$str2="lll,mmm,nnn";
$str3="xxx yyy zzz";

$pattern="/^.*?(?=[ ,\n]+)/";

$data=preg_match($pattern,$str1,$match);
print $match[0]."<br>";

$data=preg_match($pattern,$str2,$match);
print $match[0]."<br>";

$data=preg_match($pattern,$str3,$match);
print $match[0]."<br>";
?>

なお、split()は使っていはいけません。
http://www.php.net/manual/ja/function.split.php


人気Q&Aランキング

おすすめ情報