htmlのテキストデータから特定のタグに書かれてある一部の内容を抜き出したい、なんてことがあります。

Webクローリングのコードを書いていたりすると、よく遭遇しますね。

例えば、以下のようなhtmlからimgタグに設定してある画像のURLを抜き出したい、としましょう。

<body>
  <!-- 省略 -->
  <img src="https://example.com/sample1.png" />
  <img src="https://example.com/sample2.png" />
  <img src="https://example.com/sample3.png" />
  <!-- 省略 -->
</body>

こういうとき正規表現は便利で、Rubyならscanメソッドで正規表現を使って抜き出すことが可能です。

正規表現自体は以下のような感じ。

src=から次の"(ダブルクォート)までに設定してある文字列((.*?))を取ってくる、といった内容です。

(.*?)の末尾の?がポイント。

これをつけないと、一番最後の"(ダブルクォート)まで拾ってきてしまうのでこちらが想定してとおりに抽出してくれません。

/<img src="(.*?)"/

あとはこの正規表現を以下のようにscanメソッドで指定してあげればごそっと抜き出してくれます。

scanメソッドは実行すると設定した正規表現にマッチしたものを全て配列に入れて返してくれます。

あとはこれをeachとかmapのブロックで好きなように取り扱えばいい感じ。

# body変数に上記のHTMLの文字列が入っている想定
body.scan(/<img src="(.*?)"/).each do |url|
  puts url.first
end

ダブルクォート以外にシングルクォートも混ざっているようなhtmlならこんな風にしてあげればいけると思います。

/<img src=["'](.*?)["']/

以前、正規表現チェッカーを作ったので、よかったらこちらで試してみてください。

こちらはscanメソッドは使っていないので、最初のひとつしか一致しません。

正規表現を素早くキメる。正規表現チェッカーのRegExpress

この記事の環境情報

  • Ruby 3.1.2
  • ぐっすり眠ることができた