ある文字列リテラル、あるいは文字列変数の中から、正規表現に一致する部分文字列を抽出するには、String#slice(Regexp)
を使用できます。
s = 'ABCDEFG'
m = s.slice(/C.+/)
if m
puts m #=> "CDEFG"
else
puts 'Not found'
end
正規表現に一致する文字列が見つからない場合は、slice
メソッドは nil
を返します。
Regexp
クラスを使用すると、もう少し柔軟に部分文字列を抽出することができます。
下記の例では、最初に見つかった数値と、2番目に見つかった数値を抽出しています。
re = Regexp.new('(\d+)[^\d]+(\d+)')
s = 'AAA123BBB456CCC'
m = re.match(s)
if m
puts m[0] # => "123BBB456" # パターン全体と一致した部分文字列
puts m[1] # => "123" # 1番目のカッコ内と一致した部分文字列
puts m[2] # => "456" # 2番目のカッコ内と一致した部分文字列
puts m[3] # => nil
else
puts 'Not found'
end
パターンに一致する部分文字列が見つからない場合は、Regexp#match
の戻り値は nil
になるので、上記のように必ず if
分岐させて処理しましょう。
同じパターンで繰り返し出現する文字列を、配列の形ですべて抽出したいときは String#scan
を使用するのが簡単です。
s = "AAA BBB CCC"
arr = s.scan(/\w+/)
arr.each { |x| puts x }
AAA
BBB
CCC
正規表現パターン内を括弧((
と )
)でグルーピングすれば、その単位で一致部分を抽出することができます。
パターン内に括弧を含む場合は、String#scan
の戻り値は2次元配列になることに注意してください。
2次元目の各要素が、グループごとに一致した部分文字列になります。
s = 'AAA:100 BBB:200 CCC:300'
arr = s.scan(/(\w+):(\w+)/)
arr.each { |x| puts "#{x[0]} -- #{x[1]}" }
AAA -- 100
BBB -- 200
CCC -- 300