重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

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>' ;

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

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;
?>
    • good
    • 0
この回答へのお礼

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

まだまだPHP初心者のため、これからもっと学んでいきたいと思います。
また困ったらご相談させて下さい。ありがとうございました。

お礼日時:2008/09/15 14:17

ANo.2 続き



>> 正規表現とurlencodを組み合わせて、エンコードをした上で
>> パラメータに変換することは可能でしょうか。

可能です。
先回提示した正規表現はリンク先アドレスのurlencode有無に影響されないはずです。お試しください

この回答への補足

すみません。
前述したソースが誤っていたので訂正させていただきました。
何かお気づきの点がありましたら、ご指摘をお願い致します。

$pattern = '/(<a href=")(.*?\.)(pdf|doc|xls)/ie';
$replacement = '"$1".\'/download.php?file_pass=\'.urlencode("$2"."$3")';
$html = preg_replace($pattern, $replacement, $html);

補足日時:2008/09/15 14:39
    • good
    • 0
この回答へのお礼

返事が遅くなって申し訳ありませんでした。

正規表現で置換を行いながら、ファイルのパス部分を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を行うようにしました。

お礼日時:2008/09/15 14:08

こんな感じでしょうか?出力を見やすくするため


(勝手に、元の$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;
?>

この回答への補足

ご指導ありがとうございます。
教えて頂いたソースで正常に動作致しました。

ただ、
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>' ;

度々申し訳ございません。
宜しくお願い致します。

補足日時:2008/09/12 13:52
    • good
    • 0

パラメータはurlencodeしないとそのままだとたぶん通らないですが


大丈夫なのでしょうか?
    • good
    • 0
この回答へのお礼

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

お礼日時:2008/09/11 23:01

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