[PHP]正規表現で文字列内の指定文字をhtmlタグを置き換えて、さらに出力する方法を教えてください。


↓検索・置き換え対象
$data = "IMG[1]<br />一つ目の画像<br />IMG[2]<br />二つ目の画像";

↓下のファンクションに渡し
IMG_DATA($data);

↓指定した"IMG[***]"の数字を取り出してDBに登録しているアドレスを取り出す
function IMG_DATA($a){
preg_match_all("/IMG\(([\d]+)\)/",$a,$keywords,PREG_SET_ORDER);
foreach ($keywords as $val){
$data_no = htmlspecialchars($val[1]);
$data_list = mysql_query("select * from img where id = $data_no");
while($src = mysql_fetch_array($data_list)){
$img_data = "<p><img src='$src[0]' /></p>";//$srcは画像のURLが入っています。
$img_last = mb_ereg_replace("/$val[0]/",$a,$img_data);
print "$img_last";
}
}
}

上記でとりあえず検索・置き換え対象からimgタグに変換することは出来たのですが、
目的としては、

↓「目標」
[画像]
1つ目の画像
[画像]
2つ目の画像

としたかった所が

↓「現実」
[画像]
[画像]

となって画像以外のデータがどこかへ行ってしまいます。
目標にするためにはどういった修正を行えばいいでしょうか?

初めてなもので質問する要領が判らないのですがお願いします。

環境はPHP5・UTF-8・WindowsXPです。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/10/22 21:42:58
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:makeworld No.2

回答回数75ベストアンサー獲得回数23

ポイント80pt

こんな感じでしょうか。

function IMG_DATA($a){
  preg_match_all("/IMG\(([\d]+)\)/",$a,$keywords,PREG_SET_ORDER);
  foreach ($keywords as $val){
    $val[0] = strtr($val[0], array('(' => '\(', ')' => '\)'));
    $data_no = htmlspecialchars($val[1]);
    $data_list = mysql_query("select * from img where id = $data_no");
    while($src = mysql_fetch_array($data_list)){
      $img_data = "<p><img src='$src[0]' /></p>";//$srcは画像のURLが入っています。
      $img_last = mb_ereg_replace($val[0], $img_data, $a);
      if($img_last !== FALSE) $a = $img_last;
    }
  }
  print $a;
}
  • $val[0]の中の括弧『( )』をエスケープする必要があります (strtr( )の部分)
  • mb_ereg_replace( )の正規表現に、最初と最後のスラッシュ(/)は不要です
  • 途中で結果を表示せずに、最後に表示しています
id:goolin

具体的なコード提示ありがとうございます!

正規表現をちゃんと勉強し始めたばかりなので助かります。

今テストできる環境ではないので明日試して見ます。

ありがとうございました

2009/10/22 21:41:05

その他の回答1件)

id:mattn No.1

回答回数104ベストアンサー獲得回数23

ポイント30pt

http://www.php.net/ URLダミー

preg_match_all("/IMG\(([\d]+)\)/",$a,$keywords,PREG_SET_ORDER);

ではなく

preg_match_all("/IMG\[([\d]+)\]/",$a,$keywords,PREG_SET_ORDER);

かと思います。

[]

は文字クラスを示すので実際の文字として検索するにはエスケープする必要があります。

\[\]
id:goolin

ご回答ありがとうございます、質問するコードを間違えていたとは・・・

質問が下手で申し訳ありません;;、IMG(1)とIMG(2)の画像の置き換えは出来たのですが、IMG(1)とIMG(2)以外の文字"一つ目の画像・・・二つ目の画像"表示をどうしても表示出来なくて困っていました。

二度手間で申し訳ありませんが教えていただけませんでしょうか?orz

2009/10/22 17:29:01
id:makeworld No.2

回答回数75ベストアンサー獲得回数23ここでベストアンサー

ポイント80pt

こんな感じでしょうか。

function IMG_DATA($a){
  preg_match_all("/IMG\(([\d]+)\)/",$a,$keywords,PREG_SET_ORDER);
  foreach ($keywords as $val){
    $val[0] = strtr($val[0], array('(' => '\(', ')' => '\)'));
    $data_no = htmlspecialchars($val[1]);
    $data_list = mysql_query("select * from img where id = $data_no");
    while($src = mysql_fetch_array($data_list)){
      $img_data = "<p><img src='$src[0]' /></p>";//$srcは画像のURLが入っています。
      $img_last = mb_ereg_replace($val[0], $img_data, $a);
      if($img_last !== FALSE) $a = $img_last;
    }
  }
  print $a;
}
  • $val[0]の中の括弧『( )』をエスケープする必要があります (strtr( )の部分)
  • mb_ereg_replace( )の正規表現に、最初と最後のスラッシュ(/)は不要です
  • 途中で結果を表示せずに、最後に表示しています
id:goolin

具体的なコード提示ありがとうございます!

正規表現をちゃんと勉強し始めたばかりなので助かります。

今テストできる環境ではないので明日試して見ます。

ありがとうございました

2009/10/22 21:41:05
  • id:mattn
    あと余談ですが、htmlspecialchars()は出力の際に特殊文字をよろしく変換してくれる関数なので、data_noに使用すべきでないかと思います。単純に文字列を数値に変換するのであればintvalを使うべきですね。:-)
  • id:kn1967
    まったく関係無い部分への突っ込み回答とコメントだけとは・・・。
    即時回答がついていたので、環境も時間もあったのだけど回答控えたのに・・・。


    今、検証できる環境に無いので以下、コメントだけつけさせてもらいます。

    まずは、ちょっと整理しなおしましょう。
      $a オリジナル
      $img_last 追加部分
    print で出力しているのは「追加部分のみ」だから、
    どこかへ行ったのではなくて、単に出力し忘れているだけの話に気づかれましたか?

    どのような形で対処するのが良いのかは元のデータ次第だと思うけど、
    (対処例1)
      $keywords 取得時に <br />一つ目の画像 まで含んだ形で取得するようにする。
    (対処例2)
      $img_last 作成時に再度 $a から <br />一つ目の画像 の部分を取得する。
    のいずれかかな・・・。

    検証できる環境にないので、あとは自力でがんばってね。
  • id:goolin
    >>kn1967 さん
    単純に出力していなかった訳ですね・・・
    おかげで新しい考え方が見えたような気がします。
    ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません