読者です 読者をやめる 読者になる 読者になる

プログラミングノート

一からものを作ることが好きなエンジニアの開発ブログです。

正規表現のまとめ

Ruby

分かりやすいページがなかったのでメモっとく。

基本

"文字列" =~ /正規表現/

基本はこれだけで、マッチすれば特殊変数に結果がセットされ、しなければnilが返る。

  • $` マッチした箇所の前
  • $& マッチした箇所
  • $' マッチした箇所の後
"Hello Regular Expression." =~ /Regular/
print "#{$`}<<#{$&}>>#{$'}"

# Hello <<Regular>> Expression.

Perlライクに$1〜9で、グループ化した箇所を取得できる。

"Hello <b>Regular</b> Expression." =~ /<b>(.*?)<\/b>/
print $1

# Regular

(.*?)としているのはデフォルトでできるだけ長い文字列とマッチしようとするからで、指定しないと同じタグが複数ある場合に思った結果にならなかった。

"Hello <b>Regular</b> <b>Expression</b>." =~ /<b>(.*)<\/b>/
print $1

# Regular</b> <b>Expression

抽出

String#scanでマッチした箇所を全て抽出できる。便利!

p "Hello <b>Regular</b> <b>Expression</b>.".scan(/<b>(.*?)<\/b>/)

# [["Regular"],["Expression"]]

置換

String#gsubでマッチした箇所を全て置換。
String#subは最初にマッチした箇所のみ置換

p "Hello <b>Regular</b> <b>Expression</b>.".gsub(/(<.*?>)/, '')

# Hello Regular Expression.

正規表現クラス

正規表現リテラルRegexp、マッチデータはMatchDataクラスインスタンスに格納されているので、下記のように検索することも出来る。

str = "Hello <b>Regular</b> Expression."
data = /<b>(.*?)<\/b>/.match(str)

p data[0]          # $& と等価
p data[1]          # $1 と等価
p data.pre_match   # $` と等価
p data.post_match  # $' と等価
p data.offset(0)   # マッチ箇所のインデックス [開始, 終了+1]
p data.length      # マッチした数

# "<b>Regular</b>"
# "Regular"
# "Hello "
# " Expression."
# [6, 20]
# 2

特定サイトからリンクを抽出

試しにリンクだけ抽出してみた。特定ファイル(拡張子)だけダウンロードまでしたかったけど途中で力尽きたので今回はここまで。。

require 'open-uri'

str = ""
open("http://www.google.co.jp") do |r|
  r.each do |l|
    str += l
  end
end

reg = /href=['"](.*?)['"]/
str.scan(reg).each do |item|
    puts item
end