gsub(...) public

Returns a copy of str with all occurrences of pattern replaced with either replacement or the value of the block. The pattern will typically be a Regexp; if it is a String then no regular expression metacharacters will be interpreted (that is /\d/ will match a digit, but '\d' will match a backslash followed by a ‘d’).

If a string is used as the replacement, special variables from the match (such as $& and $1) cannot be substituted into it, as substitution into the string occurs before the pattern match starts. However, the sequences \1, \2, and so on may be used to interpolate successive groups in the match.

In the block form, the current match string is passed in as a parameter, and variables such as $1, $2, $`, $&, and $' will be set appropriately. The value returned by the block will be substituted for the match on each call.

The result inherits any tainting in the original string or any supplied replacement string.

   "hello".gsub(/[aeiou]/, '*')              #=> "h*ll*"
   "hello".gsub(/([aeiou])/, '<\1>')         #=> "h<e>ll<o>"
   "hello".gsub(/./) {|s| s[0].to_s + ' '}   #=> "104 101 108 108 111 "
Show source
Register or log in to add new notes.
March 31, 2010
3 thanks

Interpolating

Note that to interpolate, the sequences must be inside single quotes:

# replace /ll/ with itself
'hello'.gsub(/ll/, '\0') # returns 'hello'
'hello'.gsub(/ll/, "\0") # returns 'he\000o'
December 31, 2009
2 thanks

Replacing with "\" and match — a simple solution

A somewhat different approach to the same problem:

v.gsub(/(?=\W)/, '\\') #=> Foo\ Bar\!

But from what you are trying to achieve I suspect you might be interested in Regexp.escape method :)

December 3, 2009
2 thanks

Replacing with "\" and match

If you’re trying to place a “" in front of your matches, you’ll quickly see that it is a pain in the ass to add the quoting in the replacement string.

Here’s an example:

v = "Foo Bar!"  # Target: Foo\ Bar\!
# Resulting strings will not be quoted to decrease
# the amount of backslashes. Compare \\! to "\\\\!"

v.gsub(/\W/, '\0') #=> Foo Bar!

# \\ escapes to a literal \, which next to the 0 becomes \0
v.gsub(/\W/, '\\0') #=> Foo Bar!

# \\\0, means "\ \0", or "escaped \0"
v.gsub(/\W/, '\\\0') #=> Foo\0Bar\0

# Same mechanism as before. \\ → \
v.gsub(/\W/, '\\\\0') #=> Foo\0Bar\0

# Finally! We have now an escaped \ before \0 and
# we get the results we want.
v.gsub(/\W/, '\\\\\0') #=> Foo\ Bar\!

# It's very tempting to just write it like this now, right?
v.gsub(/\W/) { |m| "\\#{m}" } #=> Foo\ Bar\!
# It might not be shorter, but anyone can understand it.

Surely, there must be an easier way to do this. I haven’t found it, though. Hopefully, this makes it easier for you to understand why it behaves the way it does. :-)

April 4, 2011
2 thanks

Working with match captures

Let’s say you wanted to filter out passwords from:

s = "password=bob&password=jim&password=jane"

You’d do this:

r = /password\=([^\&]+)/
s.gsub!(r) { |m| m.gsub!($1, "[FILTERED]") }

Which would return

password=[FILTERED]&password=[FILTERED]&password=[FILTERED]
March 25, 2010
0 thanks

RE: Replacing with "\" and match — a simple solution

Thanks. No, I am not trying to quote for a regex. It was mostly an approach thing since I came into contact with the behavior previously when I played around. After doing some tests, I figured I should spare any other adventurers that part. :-)