• ベストアンサー

【PHP】正規表現でHTMLを置換したいのですが・・・

HTMLのソースを、正規表現で置換をしてから画面に出力したいのですが、どのような正規表現を記述すればいいのか分からず困っています。。。。 下記(befor)の4つのリンクのうち、ファイルの拡張子が、pdf、doc、xlsのファイルだけ「download.php」というPHPのプログラムを通してからダウンロードさせるために、文字列を(after)の様に置換をしたいのですが、なかなかうまくいきません。。。 どなたか、ご指導のほど宜しくお願いいたします。 (befor) $html = '<a href="/files/aaaa.pdf">あ</a><br>' . '<a href="/files/cccc.html">い</a><br>' . '<a href="/files/dddd.doc">う</a><br>' . '<a href="/files/eeee.xls">え</a><br>' ; (after) $html = '<a href=download.php?url=/files/aaaa.pdf>あ</a><br>' . '<a href="/files/cccc.html">い</a><br>' . '<a href=download.php?url=/files/dddd.doc>う</a><br>' . '<a href=download.php?url=/files/eeee.xls>え</a><br>' ;

  • PHP
  • 回答数5
  • ありがとう数5

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

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

蛇足・・・ #2さんのパターンは悪いとはいいませんが、きちんとマッチしていません。 preg_match_allでみるといいでしょう。 私のパターンはこの例ではマッチしていますが、もちろんバグがないとは いいきれません。 正規表現は思わぬ落とし穴があるので、検証をきちんとしてから実装するよう 心がけてください。 <? $html = '<a href="/files/aaaa.pdf">あ</a><br>' . '<a href="/files/cccc.html">い</a><br>' . '<a href="/files/dddd.doc">う</a><br>' . '<a href="/files/eeee.xls">え</a><br>' ; //きちんとマッチしてない $pattern = '/(<a href=")(.*?\.)(pdf|doc|xls)/ie'; preg_match_all($pattern,$html,$matches); foreach($matches[0] as $val){ print htmlspecialchars($val)."<br>"; } print "<hr>"; //マッチしている $pattern = '/(<a href=\")([^\"]*?\.(pdf|doc|xls))\"/i'; preg_match_all($pattern,$html,$matches); foreach($matches[0] as $val){ print htmlspecialchars($val)."<br>"; } ?>

その他の回答 (4)

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

urlencodeを実装する場合・・・なんか非効率なんでもっと改善の余地は ありそうですが、こんな感じ。 やりようによってはもっといろんな処理も入れられそうなので参考までに。 <?php $html = '<a href="/files/aaaa.pdf">あ</a><br>'. '<a href="/files/cccc.html">い</a><br>'. '<a href="/files/dddd.doc">う</a><br>' . '<a href="/files/eeee.xls">え</a><br>'; $pattern = '/(<a href=\")([^\"]*?\.(pdf|doc|xls))\"/i'; $separator=str_repeat(chr(0),10); if(preg_match_all($pattern,$html,$matches)){ foreach($matches[2] as $key=>$val){ $org[$key]=$separator.$val.$separator; $new[$key]="download.php?url=".urlencode($val); } $replacement = '$1'.$separator.'$2'.$separator.'"'; $html=preg_replace($pattern, $replacement, $html); $html=str_replace($org,$new,$html); } print $html; ?>

m_flower_s
質問者

お礼

参考ソースありがとうございます。 結局ANO3でコメントさせて頂いた手法で行うことにしたのですが、yambejpさんが教えてくださった手法だと幅広く使えそうですね。 何より私のコードは短いのですが、エスケープが混ざったりと見づらくなってしまっているのが難点です。 まだまだPHP初心者のため、これからもっと学んでいきたいと思います。 また困ったらご相談させて下さい。ありがとうございました。

  • mpx
  • ベストアンサー率71% (149/209)
回答No.3

ANo.2 続き >> 正規表現とurlencodを組み合わせて、エンコードをした上で >> パラメータに変換することは可能でしょうか。 可能です。 先回提示した正規表現はリンク先アドレスのurlencode有無に影響されないはずです。お試しください

m_flower_s
質問者

お礼

返事が遅くなって申し訳ありませんでした。 正規表現で置換を行いながら、ファイルのパス部分をurlencodeする方法に頭を悩ませていました。 mpxさんに教えて頂いたコードを下記コードのように一部内容を変更させて、使用させて頂くことになりました。 ありがとうございました。 $pattern = '/(<a href=\")(.*?\.)(pdf|doc|xls)/ie'; $r1 = '/(<a href=")(.*?\.)(pdf|doc|xls)/ie'; $r2 = '\'<a href="/download.php?file_pass=\'.urlencode("$2"."$3")'; $html = preg_replace($r1, $r2, $html); ※preg_replaceの第二引数にPHPの関数を組み込み、置換を行いながらurlencodeを行うようにしました。

m_flower_s
質問者

補足

すみません。 前述したソースが誤っていたので訂正させていただきました。 何かお気づきの点がありましたら、ご指摘をお願い致します。 $pattern = '/(<a href=")(.*?\.)(pdf|doc|xls)/ie'; $replacement = '"$1".\'/download.php?file_pass=\'.urlencode("$2"."$3")'; $html = preg_replace($pattern, $replacement, $html);

  • mpx
  • ベストアンサー率71% (149/209)
回答No.2

こんな感じでしょうか?出力を見やすくするため (勝手に、元の$htmlに改行コードを入れています) <?php $html = '<a href="/files/aaaa.pdf">あ</a><br>'."\n" . '<a href="/files/cccc.html">い</a><br>'."\n" . '<a href="/files/dddd.doc">う</a><br>'."\n" . '<a href="/files/eeee.xls">え</a><br>' ; $pattern = '/(<a href=\")(.*?\.)(pdf|doc|xls)/i'; $replacement = '${1}download.php?url=${2}${3}'; $html=preg_replace($pattern, $replacement, $html); print $html; ?>

m_flower_s
質問者

補足

ご指導ありがとうございます。 教えて頂いたソースで正常に動作致しました。 ただ、 ANo.1の方にご指摘頂いて気付いたのですが、下記のようにファイル名に日本語が含まれていた場合、urlencodeが必要になると思います。 正規表現とurlencodを組み合わせて、エンコードをした上でパラメータに変換することは可能でしょうか。 $html = '<a href="/files/あああ.pdf">あ</a><br>'."\n" . '<a href="/files/いいい.html">い</a><br>'."\n" . '<a href="/files/ううう.doc">う</a><br>'."\n" . '<a href="/files/えええ.xls">え</a><br>' ; 度々申し訳ございません。 宜しくお願い致します。

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

パラメータはurlencodeしないとそのままだとたぶん通らないですが 大丈夫なのでしょうか?

m_flower_s
質問者

お礼

すみません。 例文にurlencodeを考慮するのが漏れてしまっていました。 ご指摘ありがとうございました。

関連するQ&A

  • SQLの書き方について教えてください。

    accessについて。 シートの中に列名name、列名friendnameがあります。 name,friendname aaaa,bbbb bbbb,cccc cccc,aaaa dddd,aaaa eeee,bbbb ffff,eeee ほしいデータは aaaa,bbbb,cccc bbbb,cccc,aaaa cccc,aaaa,bbbb dddd,aaaa,bbbb eeee,bbbb,cccc ffff,eeee,bbbb と友達の友達の名前がほしいのです。 SQLの書き方を教えてください。 よろしくお願いします。

  • SQLでの集計

    下記の様に、「複数のitemを買っているuserと購入されたitem」のテーブルと、 user item ---------------------------------- 田中 AAAA 田中 CCCC 田中 EEEE 北野 DDDD 北野 BBBB 北野 AAAA 小堺 CCCC 小堺 EEEE 松本 EEEE 松本 KKKK 松本 CCCC 松本 DDDD 浜田 BBBB 浜田 DDDD 下記の様な IDに紐付いた 「item」のテーブルから、 ID  item ---------------------------------- 1   AAAA 2   BBBB 3   CCCC 4   DDDD 5   EEEE 下記の様に各itemと各itemを買った場合に一緒に買われるitemの一覧を結果 として表示させたいのですが、クエリの作り方が思い浮かばず、困っています。 ※)可能であれば、買われたitemを表示する際にはbuy1から(左側から)同時購入 回数の多いitemを重複せずに並べて表示したい ID  item  buy1  buy3  buy4  buy5  buy6・・・・ ---------------------------------- 1  AAAA CCCC BBBB DDDD EEEE 2  BBBB DDDD AAAA 3  CCCC AAAA EEEE DDDD KKKKK 4  DDDD AAAA BBBB CCCC EEEE 5  EEEE AAAA CCCC KKKKK 尚、IDと紐付いているitem数は決まっていますが、買われるitemの種類は上記 の様にIDが1~5だけではなく、集計してみないと判らない状況です。 今の所、SQLはACCESS(2003)上にて手打ちしています。 以上、ご教示のほど、宜しくお願い致します。

  • ImgBurnの使い方

    DVD焼きアプリ「ImgBurn」において、 AAAA\BBBBB\CCCC AAAA\BBBBB\DDDD AAAA\BBBBB\EEEE HDD上ではこんな感じの構成のフォルダを、DVDでは CCCC DDDD EEEE をルート直下に見えるように焼きたいのですが、どこをどのように設定すればいいでしょうか?

  • UNIXで文字列分割

    UNIXでマルチバイトの文字列で分割したいです。 例) aaaa bbbb cccc dddd eeee ffff ↓ [bbbb]で分割 [1]aaaa [2] cccc dddd eeee ffff できればawkで処理をしたいと考えています。

  • エクセルで教えて下さい。

    エクセルで教えて下さい。 オートフィルタ、ピボットテーブル以外で関数などで教えて下さい。 A列に大量の文字列があり重複したりしてます。 そこで、 B列にはA列にある大量の文字列を重複なしで表示させたいと思ってます。 例えば A列 B列 AAAA AAAA BBBB BBBB AAAA CCCC CCCC DDDD DDDD EEEE DDDD FFFF EEEE FFFF EEEE AAAA みたいな感じです。A列は編集可能でQQQQを追加すれば自動でB列にも表示させたいです。 このようなことを簡単にできますでしょうか? 宜しくお願いします。

  • 正規表現での置換について

    いつもお世話になっております。 ===例=== <a href="index.html">TEST1</a><br /> <a href="index.html?test=b">TEST2</a><br /> <a href="index.html?uid=NULLGWDOCOMO">TEST3</a><br /> <a href="index.html?test=a&uid=NULLGWDOCOMO">TEST4</a><br /> PHPのpreg_replaceを用いて リンクのパラメータに、uid=NULLGWDOCOMOがなければ付加したいのですが、 さっぱり方法がわかりません。 上記の例で、TEST1のリンクの場合は、TEST3 のように、 TEST2のリンクの場合はTEST4のようにしたいです。 もともとTEST3、TEST4のようにキーが付いてるケースもあり、そのときは無視です。 正規表現にお詳しい方よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • Access Union について

    下記2テーブルがあります。 テーブル1 品番   1月合計 AAAA   1111 BBBB   2222 CCCC   1122 EEEE   3211 テーブル2 品番   2月合計 AAAA   1211 BBBB   3222 CCCC   1522 DDDD   2223 UNIONのSQL文で下記のような結果を得たいです。 品番   1月合計  2月合計 AAAA   1111    1211 BBBB   2222    3222 CCCC   1122    1522 DDDD         2223 EEEE   3211 SQL文をどのように書いたらいいですか。ご教授,お願い致します。

  • エクセルについての質問。

    エクセルの関数に関して質問があります。 |10001|AAAA|10002|BBBB| |10002|BBBB|10004|DDDD| |10003|CCCC|10004|DDDD| |10004|DDDD|10001|AAAA| |10005|EEEE|10005|EEEE| ちょっと分かりにくいですが 一番上の行ですと、 列A=10001 列B=AAAA 列C=10002 列D=BBBB と考えて下さい。 質問です。 --------------------------- 列Cの数値を列Aから検索して 同じのがあれば列Bの数値を列Dに表示する。 --------------------------- この関数を教えて頂けませんでしょうか? 宜しくお願い致します。

  • HTML化

    phpの関数を使ったファイルは、aaa.phpのように「.php」ではないと表示できませんが、これを「.html」で表示する方法はないでしょうか? 詳細に書くと下記のような感じになります。 aaa.datデータファイル内 aaaa,bbbb,cccc dddd,eeee,ffff aaa.phpからaaa.datのデータを表示する。 これだと毎回、aaa.phpを実行するたびにaaa.datを読んでしまいますよね。 それで、aaa.phpを1回実行しaaa.datを読み込み、どうにかしてaaa.datを組み込んで、aaa.htmlにして表示したいのです。 いい知恵があったら教えて下さい。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • wordの段落を通番で振りなおしたい

    word2003で段落を設定した文書があるんですが、番号を振りなおしてつけているため、以下のようになっております。 1.aaaa 2.bbbb 3.cccc 1.dddd 2.eeee 1.ffff 2.gggg 3.hhhh これを以下のような通しの段落番号に変換することは可能でしょうか? 1.aaaa 2.bbbb 3.cccc 4.dddd 5.eeee 6.ffff 7.gggg 8.hhhh 各段落の1.を”自動的に番号を振る”を選択すればできると思いますが、数が多いため簡単な方法を探しております。 よろしくお願いいたします。