Ruby 1.9.2 リファレンスマニュアル > ライブラリ一覧 > library _builtin > class String > sub
sub(pattern, replace) -> String
文字列中で pattern にマッチした最初の部分を 文字列 replace で置き換えた文字列を生成し返します。
Ruby 1.6 以前では pattern が文字列の場合、 その文字列を正規表現にコンパイルしていました。 しかし Ruby 1.8 以降では、その文字列そのものがパターンになります。
置換文字列 replace 中の \& と \0 はマッチした部分文字列に、 \1 ... \9 は n 番目の括弧の内容に置き換えられます。 置換文字列内では \`、\'、\+ も使えます。 これらは $`、$'、$+ に対応します。
例:
p 'abcdefg'.sub(/def/, '!!') # => "abc!!g" p 'abcabc'.sub(/b/, '<<\&>>') # => "a<<b>>cabc" p 'xxbbxbb'.sub(/x+(b+)/, 'X<<\1>>') # => "X<<bb>>xbb"
注意:
第 2 引数 replace に $1 を埋め込んでも意図した結果にはなりません。 この文字列が評価される時点ではまだ正規表現マッチが行われておらず、 $1 がセットされていないからです。
また、sub では「\」が部分文字列との置き換えという特別な意味を持つため、 replace に「\」自身を入れたいときは 「\」を二重にエスケープしなければなりません。
# ひとつめの括弧の内容に置き換えるときによくある間違い p 'xbbb-xbbb'.sub(/x(b+)/, "#{$1}") # => "-xbbb" # NG p 'xbbb-xbbb'.sub(/x(b+)/, "\1") # => "1-xbbb" # NG p 'xbbb-xbbb'.sub(/x(b+)/, "\\1") # => "bbb-xbbb" # OK p 'xbbb-xbbb'.sub(/x(b+)/, '\1') # => "bbb-xbbb" # OK p 'xbbb-xbbb'.sub(/x(b+)/, '\\1') # => "bbb-xbbb" # OK # バックスラッシュを倍にするときによくある間違い puts '\n'.sub(/\\/, "\\\\") # => \n # NG puts '\n'.sub(/\\/, '\\\\') # => \n # NG puts '\n'.sub(/\\/, "\\\\\\\\") # => \\n # OK puts '\n'.sub(/\\/, '\\\\\\\\') # => \\n # OK
このような間違いを確実に防止し、コードの可読性を上げるには、 \& や \1 よりも下記のようにブロック付き形式の sub を使うべきです。
p 'xbbb-xbbb'.sub(/x(b+)/) { $1 } # => "bbb-xbbb" # OK puts '\n'.sub(/\\/) { '\\\\' } # => \\n # OK
[SEE_ALSO] String#gsub
sub(pattern) {|matched| .... } -> String
文字列中で pattern にマッチした最初の部分をブロックに渡し、 その評価結果で置き換えた新しい文字列を返します。 ブロックなしの sub と違い、ブロックの中からは 組み込み変数 $1, $2, $3, ... を問題なく参照できます。
Ruby 1.6 以前では pattern が文字列の場合、 その文字列を正規表現にコンパイルしていました。 しかし Ruby 1.8 以降では、その文字列そのものがパターンになります。
例:
p 'abcabc'.sub(/b/) {|s| s.upcase } #=> "aBcabc" p 'abcabc'.sub(/b/) { $&.upcase } #=> "aBcabc"
[SEE_ALSO] String#gsub
sub(pattern, hash) -> String
文字列中の pattern にマッチした部分をキーにして hash を引いた値で置き換えます。
hash = {'b'=>'B', 'c'=>'C'} p "abcabc".sub(/[bc]/){hash[$&]} #=> "aBCabc" p "abcabc".sub(/[bc]/, hash) #=> "aBCabc"