• ベストアンサー

正規表現でタグからURLを取り出したい

こんにちは。 <a href="http://www.x**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <img border="0" src="http://Y**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444" alt="テスト<BR>正規表現" width="100" height="75"></a> などというタグから リンク先のURLからhttp://をとったもの(ここでは、www.x**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444) と ソースURL(ここでは、http://Y**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444) を求めたいんですが、 どのように書けばいいのかわからなくて困っています。 どなたかわかりましたら、ご教授お願いいたします。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=909227 を参考にしてみましたが、この方法だと、TARGET=_blankなども入ってしまいます。

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

  • ベストアンサー
回答No.4

こんにちは。 No2です。 先ほど、『単にURLを正規表現で取り出したい』という質問に受け取ってしまいました。申し訳ございませんでした。そういう意味では述べられている質問より高度(か、同一)です。 さて、私が前回の質問で言いたかったのは正規表現の使い方と意味です。 前回述べたのは答えではありませんでしたが、考え方をわかって頂かないと違うパターンになる度にこちらの質問に書き込まなければならず、非常に質問者さんにとっても効率の良いものではありません。 前回言った「自力で出来なければ」というのはそういう意味です。 で、本題です。 正規表現にマッチするパターンが質問内容しか例がないので、その範囲内、もしくはそれにプラスしたパターンでやります。 ※それ以外については、保証の限りではありません。 そもそもタグの書き方が間違っている場合もあるでしょうし、URL自体に空白や改行を入れて書いている人もいるかもしれません。色々なパターンがあります(たとえばテーブルタグが崩れるのを防ぐためや、そもそもそのURLの先が自作のWebサーバや自作OSを使っているかもしれませんし)。 しかし、そういったパターンも考慮すると非常に大げさになってしまいます。 PHPやPerlの正規表現は非常に遅いので、大げさになればなるほどどんどん処理が遅くなります。 よって、URLであろう。もしくは、一般的なURLを対象するだけで十分でしょう。 細かい検証はしていませんが(片手間でつくったので思惑通りかどうか保証できません)、質問で言われている例、及び、以下のパターンで取り出す例を載せておきます。 (具体的な使用例を言って頂ければより正確になるでしょう。2chのような巨大な掲示板のページから取り出す。と、言うのであれば、PHPでやるべきか。と、いう問題にもなってきますし。) -------------------------- ソース -------------------------------------- <? /* リンク用のタグに使われているURLと imgタグ用に使われているURL、 そして、その他のURL を別の配列に入れる例。 */ $str = <<<EOF aaaaaaaa <a href="http://www.a**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href ="http://www.b**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href = "http://www.c**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href = http://www.d**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 TARGET=_blank> <a href = "http://www.e**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href="http://www.f**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href= http://www.g**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 TARGET=_blank> これはただのアドレスhttp://www.H**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 aaaahttp://www.H**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444ああああ <img border="0" src="http://imga**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444" alt="テスト<BR>正規表現" width="100" height="75"></a> <img src="http://imgb**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444" alt="テスト<BR>正規表現" width="100" height="75"></a> bbbbbb EOF; preg_match_all("/(\C{5,10})[\"]?https?:\/\/([^\"\s]+)/i" , $str , $arr); //より正確にするなら以下を参考に //preg_match_all("/(\C{5,10})[\"]?https?:\/\/([[:alnum:]\+\$\?\.%,!#~\*\/:@&=_\-]+)/i" , $str , $arr); $linkUrl = array(); $imgUrl = array(); $etcUrl = array(); for ( $i = 0; $i < count($arr[1]); $i++){ if (stristr($arr[1][$i] , "href")){ $linkUrl[] = $arr[2][$i]; }else if (stristr($arr[1][$i] , "src")){ //httpのみにするか ftp や https その他に対応させることも可 //今回は http のみに対応ということで $imgUrl[] = "http://" . $arr[2][$i]; }else{ $etcUrl[] = $arr[2][$i]; } } header("Content-Type: text/plain; "); print "LinkっぽいURL<BR>\n"; print_r($linkUrl); print "\n\n"; print "imgタグっぽいURL<BR>\n"; print_r($imgUrl); print "\n\n"; print "その他のURL<BR>\n"; print_r($etcUrl); ?> -------------------------- 実行結果 -------------------------------------- LinkっぽいURL<BR> Array ( [0] => www.a**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [1] => www.b**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [2] => www.c**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [3] => www.d**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [4] => www.e**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [5] => www.f**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [6] => www.g**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 ) imgタグっぽいURL<BR> Array ( [0] => http://imga**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444 [1] => http://imgb**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444 ) その他のURL<BR> Array ( [0] => www.H**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444 [1] => www.H**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444ああああ )

syamo2
質問者

お礼

ありがとうございます。 私なりに解説サイトをみながらやってみたのですが、 なかなかうまくできなかったのですが、とても参考になりました。 おっしゃるとおり、これからはもっと自力でとけるようにしていきたいと思いますm(_ _)m スクリプトとして実行してみましたが、すべて希望通りに動いてくれました! リンク、画像だけでなくその他のURLも拾ってくれるので、すごく便利ですね。 このたびは、どうもありがとうございました。

その他の回答 (3)

  • randman
  • ベストアンサー率51% (17/33)
回答No.3

preg_match_all("/(?:href|src)\s*=\s*(\".+?\"|\'.+?\'|[^\s>]+)\s*/is",$html,$matches,PREG_SET_ORDER); でマッチしたものに、 preg_match("/^[a-zA-Z]+\:\/\/(.+)/s",$url,$matches); ※[a-zA-Z]+は[http|https|ftp…などなど]でも可。 をマッチさせるのが簡単かな。httpの部分はpreg_replaceで削除してもいいけど。 もちろん、これは完全じゃない。完全なURLマッチングは非常に難しい。 http://www.din.or.jp/~ohzaki/perl.htm#URI さらにタグの内部にあるかどうかを知るのも難しい(上のやり方ではタグの内外、コメントの内外であるかどうかは不明)。 http://www.din.or.jp/~ohzaki/perl.htm#HTML_Tag とにかく、一回のマッチで全てを求めようとしちゃいけない。あらかじめ、コメントやタグの外の部分を削除しておくとか。 少なくとも、No.2のやり方は「答え」じゃない。

syamo2
質問者

お礼

ありがとうございます。 なるほど、少しずつ希望の形にしていくということですね。 試してみましたが preg_match("/^[a-zA-Z]+\:\/\/(.+)/s",$url,$matches); の行で、うまく検出されませんでした。 もちろん$urlをその前の行のマッチしたものにしてますが・・・ [a-zA-Z]を[http|https]にしたり その後ろの+\:\/\/を:\/\/にしたんですが・・・ もっと勉強します!ありがとうございました。

回答No.2

こんにちは。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=909227 よりもやさしい部類ですよ。 これが自力で出来なければ、正規表現は一生マスターできません。 最初から一発でとは言いませんが、試行錯誤してやってみてください。 一応、答えを載せておきます。 「こういう場合は・・・」「こうしたいんだけれど・・・」という部分があれば、ご自分で色々試行錯誤してください。 ------------ここから-------------------- <? $str = <<<EOF aaaaaaaa <a href="http://www.x**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href="http://www.a**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href="http://www.b**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <a href="http://www.c**.com/test/product.php?id=1111&pid=2222&hid=3333&oid=4444" TARGET=_blank> <img border="0" src="http://Y**.com/include/implession.php?pid=2222&hid=3333&flag1=product&id=1111&oid=4444" alt="テスト<BR>正規表現" width="100" height="75"></a> bbbbbb EOF; preg_match_all("/(https?:\/\/[^\"]+)/i" , $str , $arr); print_r($arr); ?> ------------------------------------------ 上を実行されるとわかると思いますが、取り出すときは $arr[0][0]~$arr[0][最後の要素] でアクセスできます。 $arr[0] と $arr[1]の違いは今回の場合は気にしなくていいでしょう。同じものをさしています。

  • moon_night
  • ベストアンサー率32% (598/1831)
回答No.1

たとえば、 heaf=" から 次の " までとか。 srcも同様に。 ただ、クウォーテーションで閉じてない場合はだめだけど。 その場合は ”(または ' )があるかないかで、終わりは半角スペースまでとか。

syamo2
質問者

お礼

ありがとうございます。 最初その方法を考えたんですが、どうもうまくいかないURLがあって・・・

関連するQ&A