gsub(*args) public

Returns a copy of str with the all occurrences of pattern substituted for the second argument. The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. ‘\d’ will match a backlash followed by ‘d’, instead of a digit.

If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern’s capture groups of the form \d, where d is a group number, or \k<n>, where n is a group name. If it is a double-quoted string, both back-references must be preceded by an additional backslash. However, within replacement the special match variables, such as &$, will not refer to the current match.

If the second argument is a Hash, and the matched text is one of its keys, the corresponding value is the replacement string.

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.

When neither a block nor a second argument is supplied, an Enumerator is returned.

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


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

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. :-)