rubyguides

String#gsub

String#gsub replaces every occurrence of a pattern in a string. The g means global — it replaces all matches, not just the first one. The original string is never modified.

Signature

str.gsub(pattern, replacement)
str.gsub(pattern) { |match| block }

Parameters:

  • pattern — a String or Regexp
  • replacement — a String, Hash, Symbol, or nil

Returns: String — a new string with all replacements

The bang variant gsub! modifies in place and returns the number of replacements, or nil if nothing matched.

String Pattern Replacement

"hello world".gsub("o", "0")      # => "hell0 w0rld"
"a b a b a b".gsub("a", "X")   # => "X b X b X b"

String patterns match literally — no regex features, just exact substring replacement.

Regex Pattern Replacement

"hello123world456".gsub(/\d+/, "NUMBER")
# => "helloNUMBERworldNUMBER"

"foo bar foo".gsub(/foo/, "baz")
# => "baz bar baz"

Regex patterns enable capture groups, character classes, and quantifiers.

Block Form

Pass a block and each match gets replaced with the block’s return value:

"hello world".gsub(/\w+/) { |word| word.upcase }
# => "HELLO WORLD"

"123-456-7890".gsub(/\d+/) { |n| n.to_i * 2 }
# => "246-912-15780"

The block receives the matched string. Whatever it returns becomes the replacement.

Backreferences

Use \1 through \9 in the replacement string to reference captured groups:

"John Doe".gsub(/(\w+) (\w+)/, '\2, \1')
# => "Doe, John"

"hello".gsub(/(.)/, '[\1]')
# => "[h][e][l][l][o]"

Named captures use \k<name>:

"John Doe".gsub(/(?<first>\w+) (?<last>\w+)/, '\k<last>, \k<first>')
# => "Doe, John"

Hash Replacement

Pass a Hash to substitute matches based on their content:

replacements = {
  "hello" => "hi",
  "world" => "earth",
  "!" => "."
}

"hello world!".gsub(/\w+|!/, replacements)
# => "hi earth."

If a match has no key in the hash, it passes through unchanged.

Symbol as Replacement

A Symbol calls that method on the matched string:

"hello".gsub(/\w+/, :upcase)    # => "HELLO"
"hello".gsub(/\w+/, :length)    # => "5"
"hello world".gsub(/\w+/, :capitalize)
# => "Hello World"

Special Replacement Sequences

Some sequences in replacement strings have special meaning:

SequenceBecomes
\\A literal backslash
\nNewline
\tTab
&The entire matched string
\`The part before the match
\'The part after the match
\+The last matched group
"hello".gsub("ello", 'goodbye &')
# => "goodbye hello"

"world".gsub(/(world)/, 'hello, \\` & \\\'')
# => "hello,  world"

The Bang Variant

gsub! modifies the string in place:

s = "hello world"
n = s.gsub!("o", "0")
s   # => "hell0 w0rld"
n   # => 2  (replacement count)

When nothing matches, gsub! returns nil:

s = "hello"
result = s.gsub!("x", "y")
result  # => nil

Use gsub! when you need the replacement count or want to modify in place. Otherwise prefer gsub.

Counting Without Allocating a New String

count = 0
"hello world".gsub(/\w+/) { count += 1 }
count  # => 2

gsub vs sub

MethodMatches replacedReturns
subFirst onlyNew string
gsubAllNew string
sub!First onlyString or nil
gsub!AllString or nil

Common Patterns

Normalizing Whitespace

"hello  \n  world".gsub(/\s+/, " ")
# => "hello world"

Redacting Words

sensitive = ["password", "secret", "token"]
replacements = Hash[sensitive.product(["[REDACTED]"]).to_h]

"use your password here".gsub(/\w+/, replacements)
# => "use your [REDACTED] here"

Converting Snake Case to CamelCase

"hello_world".gsub(/_(\w)/) { $1.upcase }
# => "helloWorld"

$1 is set by gsub’s block form, referencing the first capture group.

See Also