Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Ruby辞典

  1. トップページ
  2. Ruby辞典
  3. 文字列.scan / match / =~

文字列.scan / match / =~

文字列に対して正規表現を使ってパターン検索を行うメソッドです。全マッチを配列で取得したり、MatchDataオブジェクトで詳細情報を取得したりできます。

構文
# パターンにマッチした文字列をすべて配列で返します。
文字列.scan(/パターン/)
文字列.scan(/パターン/) { |マッチ| 処理 }

# 最初のマッチの MatchData を返します(マッチしない場合は nil)。
文字列.match(/パターン/)
文字列.match(/パターン/, 開始位置)

# マッチした位置を返します(=~ と同じ)。
文字列 =~ /パターン/
メソッド一覧
メソッド概要
scan(pattern)パターンにマッチする部分文字列をすべて配列で返します。キャプチャグループがある場合は配列の配列を返します。
scan(pattern) { |m| }マッチするたびにブロックを呼び出します。
match(pattern)最初にマッチした位置のMatchDataを返します。マッチしない場合は『nil』を返します。
match(pattern, pos)pos番目の文字から検索を開始します。
=~マッチした最初の位置(整数)または『nil』を返します。
サンプルコード
文章 = "Rubyは1995年に生まれ、バージョン3.2が2022年にリリースされました。"

# scan で数字をすべて抽出します。
数字 = 文章.scan(/\d+/)
puts 数字.inspect  # ["1995", "3", "2", "2022"]

# キャプチャグループを使って年と月を分けて取得します。
日付文字列 = "予定: 2024-01-15, 2024-03-20, 2024-06-01"
日付一覧 = 日付文字列.scan(/(\d{4})-(\d{2})-(\d{2})/)
puts 日付一覧.inspect
# [["2024", "01", "15"], ["2024", "03", "20"], ["2024", "06", "01"]]

# ブロックを使って処理します。
puts "マッチした日付:"
日付文字列.scan(/\d{4}-\d{2}-\d{2}/) { |date| puts "  #{date}" }

# match で最初のマッチの詳細情報を取得します。
html = "<h1>タイトル</h1>"
m = html.match(/<(\w+)>(.+?)<\/\1>/)
if m
  puts "タグ: #{m[1]}"     # タグ: h1
  puts "内容: #{m[2]}"     # 内容: タイトル
end

# match で開始位置を指定します。
テキスト = "apple banana apple cherry"
m1 = テキスト.match(/apple/)
puts m1[0]  # apple(最初のマッチ)
m2 = テキスト.match(/apple/, 6)
puts m2[0]  # apple(6文字目以降から検索)
puts m2.begin(0)  # 14(2番目の apple の位置)
概要

『scan』はすべてのマッチを一度に取得したいときに使います。キャプチャグループなしの場合は文字列の配列、キャプチャグループありの場合は配列の配列を返します。これを利用してデータ抽出に活用できます。

『match』は最初のマッチだけが必要な場合や、マッチ位置・前後の文字列など詳細情報が必要な場合に使います。戻り値の『MatchData』には『begin(n)』(マッチ開始位置)、『end(n)』(マッチ終了位置)、『pre_match』、『post_match』などのメソッドがあります。

HTMLやXMLのパースに正規表現を使うことは推奨されません。入れ子構造や属性の順序など、正規表現では正確に処理できないケースが多くあります。HTMLのパースには専用のライブラリ(Nokogiriなど)を使用してください。

正規表現の基本構文については『Regexp.new / =~ / match』を、文字列の置換には『文字列.sub / gsub』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。