LoginSignup
15
15

More than 3 years have passed since last update.

gsubで正規表現を用いた置換を行う際、$1でグループの参照がうまくいかない場合は'\1'を使え、またはブロックを使え

Last updated at Posted at 2015-06-18

結論

$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"  

参考

Link

Original: gsubで正規表現を用いた置換を行う際、$1でグループの参照がうまくいかない場合は'\1'を使え

15
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
15