[PHP]HTMLから全ての画像URLを正規表現で取得する方法

ブログ記事から画像を抜き出したい

わたしは今、とあるアプリを開発中です
いわゆるまとめのまとめ系アプリなのですが、、、

アプリを開発する中で、取得したRSSの記事情報から画像を抜き出したくなりました。
記事のタイトルと一緒に画像も見せたいからです。

そんな時はやっぱり正規表現だね!

PHPでどう書くか

定期的に各ブログさんの記事を収集してDBに放り込む処理はサーバで行っています。
そして、サーバサイドはお手軽簡単なPHPにて構築

PHPで正規表現使うのは下記の関数です

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
http://php.net/manual/ja/function.preg-match.php

int preg_match_all ( string $pattern , string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int$offset = 0 ]]] )
http://php.net/manual/ja/function.preg-match-all.php

preg_match

preg_matchでは、$subjectで指定した文字列に対して$patternで正規表現検索を行い、返ってきた値を1つ$matchesに保存します。
この時、$matchesは1次元配列となります($matches[])

$matches[0]は検索にひっかかった全ての文字列
$matches[1]は1 番目のキャプチャ用サブパターンにマッチした 文字列

 

preg_match_all

preg_matchとはことなり、検索に引っかかったものを全て取得します

使い方はpreg_matchと同様、$subjectで指定した文字列に対して$patternで正規表現検索を行います。
また、$matchesは2次元配列となります($matches[][])

配列の中身は$flagsで指定した値によって異なります。

$flags = PREG_PATTERN_ORDER

$matches[0] ・・・ パターン全体にマッチした文字列の配列
$matches[1] ・・・ 第 1 のキャプチャ用サブパターンにマッチした文字列の配列

$flags = PREG_SET_ORDER

$matches[0] ・・・ 1 回目のマッチングでキャプチャした値の配列
$matches[1] ・・・ 2回目のマッチングでキャプチャした値の配列

というかんじですが、基本的にはPREG_PATTERN_ORDERの指定で良いんじゃないかな
($flagsはoptionalなので、指定しない場合はPREG_PATTERN_ORDERとなる)

早く画像の取り方教えろ!

説明はもうおいておいて、、、
(わからんかったら上記リンクのマニュアルを見てください)

私が実際に書いたコードは下記のような感じです。


$rssImage = '';
$preg_string = '/<img.*?src\s*?=\s*?[\"|\'](.*?(jpg|jpeg|gif|png))[\"|\'].*?>/i';
if(preg_match_all($preg_string, $rssDescription, $match, PREG_PATTERN_ORDER) > 0){

  // gifは除外(jpenのみ採用)
  foreach ($match[1] as $image) {
    if(preg_match('/.*?(jpg|jpeg)/i', $image, $out)){
      $rssImage = $image;
      break;
    }
  }
  echo 'check: ' . $rssImage . PHP_EOL;
}

はじめのpreg_match_allで、RSSのdescriptionからすべての画像を取得しています。
全ての画像と言っても、jpg,jpeg,gif,pngだけです。

画像は<img>タグで判断できますね。
<img>タグのsrc部分を抜き出している形です。

/<img.*?src\s*?=\s*?[\”|\’](.*?(jpg|jpeg|gif|png))[\”|\’].*?>/i

この後が問題
画像を取得したはいいけど、gifとかpngとかっていうのはブログ内の絵文字だったりするんですね。

そんなものは必要ない!!

だからpreg_match_allで取れた配列に対して、jpg,jpegのみ採用しているんです。

いやしかし、個人的にはあまり気に入っていないのです。
もっとスマートで良い書き方があると思うのだが、、、

ひとまず機能は満たしてはいるのでおいておくとして
また見直す必要はありそうだ

正規表現をマスターするということ

プログラミングを行う上で、正規表現をマスターすることはマストだと思います。
(私自身まだマスターしていませんが、、、、、、、)

今回のように、スクレイピングを行ったり、はたまたコーディング中のソースコードに対して正規表現での検索をかけて一括置換!!
なんて便利なこともできてしまうわけです。

とはいえ正規表現ってパッと見はなにかの呪文のように見える、、、

しかし少し勉強してみれば、案外読めてしまうものです。

私も本を呼んだりしてもうちょっとちゃんと勉強しなきゃなー、、、