マッチした文字列の前後の文字列を取得($`、$')

広告

正規表現がマッチした時に、変数「$&」にはマッチした部分文字列が代入されますが、対象の文字列の中でマッチした部分よりも前の文字列が特別な変数「$`」に代入され、後の文字列が特別な変数「$'」に代入されます。

$`
$'

具体的に考えてみます。正規表現オブジェクト「/On/」に対して文字列「RubyOnRails」をマッチさせた場合、マッチに成功します。この時、変数「$&」にはマッチした部分文字列「On」が代入されますが、同時に変数「$`」には「On」より前の「Ruby」が代入され、変数「$'」には「On」より後の「Rails」が代入されます。

/On/ =~ "RubyOnRails"
$`  =>  "Ruby"
$&  =>  "On"
$'  =>  "Rails"

なお、マッチした部分の前後に文字列が存在しなかった場合は空文字が代入されます。

/OnRails/ =~ "RubyOnRails"
$`  =>  "Ruby"
$&  =>  "OnRails"
$'  =>  ""

またマッチしなかった場合には変数「$`」及び変数「$'」はいずれも「nil」が代入されます。

/Off/ =~ "RubyOnRails"
$`  =>  nil
$&  =>  nil
$'  =>  nil

Regexp.last_match.pre_match及びRegexp.last_match.post_match

Regexpクラスで用意されているクラスメソッドの「last_match」を引数無しで実行すると「MatchData」クラスのオブジェクトを取得できます。

Regexp.last_match

「MatchData」クラスのオブジェクトは正規表現が最後にマッチした時の情報を保持しているオブジェクトです。MatchDataクラスで用意されている「pre_match」メソッド及び「post_match」メソッドによってマッチした部分文字列の前後の文字列を取得できます。

Regexp.last_match.pre_match
Regexp.last_match.post_match

「Regexp.last_match.pre_match」メソッドが返す値は「$`」に代入されている文字列と同じです。同じく「Regexp.last_match.post_match」メソッドが返す値は「$'」に代入されている文字列と同じです。

/On/ =~ "RubyOnRails"
print(Regexp.last_match.pre_match + "¥n")
print(Regexp.last_match(0) + "¥n")
print(Regexp.last_match.post_match + "¥n")

上記ではそれぞれ「Ruby」「On」「Rails」が出力されます。

サンプルプログラム

では簡単なプログラムで確認して見ます。

test2-1.rb

#! ruby -Ku
require "kconv"

def check(str)
  if / .+ / =~ str then
    print(Kconv.tosjis("○") + str + "¥n")
    print("  [" + $` + "]¥n")
    print("  [" + $& + "]¥n")
    print("  [" + $' + "]¥n")
  else
    print(Kconv.tosjis("×") + str + "¥n")
  end
end

print(Kconv.tosjis("/ .+ / にマッチするかどうか¥n¥n"))

check("10 years old")
check("What would you like to have?")
check("Search results")
check("Hello")

上記のプログラムを「test2-1.rb」として保存します。文字コードはUTF-8です。そして下記のように実行して下さい。

マッチした文字列の前後の文字列を取得($`、$')

( Written by Tatsuo Ikura )