結論
$1, $2, ..., $nのかわりに\1, \2, ..., \nを使え。
2015/06/30追記
String#gsub(regex, substring)の代わりにstring#gsub(regex){ substring }を使う方を推奨。
理由はバックスラッシュのエスケープがトラブルの元となり得るため。
$1で良い場合
Regexp#match, String#match, Regexp#=~, String#=~を使う場合は$1で参照できる。
cool = 'coooooooooooooool'
regex = /.(o+)./
regex.match(cool)
puts $1
# => "ooooooooooooooo"
cool.match(regex)
puts $1
# => "ooooooooooooooo"
cool =~ regex
puts $1
# => "ooooooooooooooo"
regex =~ cool
puts $1
# => "ooooooooooooooo"
$1でダメな場合
String#gsubでは使えない。
どうだめなのか?
思っているように置換をしてくれない。しかし、puts $1で書き出すと正しく抽出できている。
# ※$1には値が既に入ってしまっているため、ここでpryを再起動し$1.nil? == trueにしてあります
cool = 'coooooooooooooool'
regex = /.(o+)./
cool.gsub(regex, "s#{$1}up")
# => "sup"
puts $1
# => "ooooooooooooooo"
どうすれば良いのか
$1の代わりに\1を使う方法
$1の代わりに\1を使いましょう。さらに式展開せず、普通の文字列として与えて下さい。
# ※`$1`には値が既に入ってしまっているため、ここでpryを再起動し`$1.nil? == true`にしてあります
cool = 'coooooooooooooool'
regex = /.(o+)./
cool.gsub(regex, 's\1up')
# => "soooooooooooooooup"
puts $1
# => "ooooooooooooooo"
ブロックを使う方法
# ※`$1`には値が既に入ってしまっているため、ここでpryを再起動し`$1.nil? == true`にしてあります
cool = 'coooooooooooooool'
regex = /.(o+)./
cool.gsub(regex){"s#{$1}up"}
# => "soooooooooooooooup"
puts $1
# => "ooooooooooooooo"
参考
- http://blog.ethanvizitei.com/2010/06/using-regex-groups-for-rubys-gsub.html
- http://ruby-doc.org/core-2.2.0/Regexp.html