rubyguides

Kernel#gsub

str.gsub(pattern, replacement) -> string

String#gsub (global substitute) replaces all occurrences of a pattern in a string. It returns a new string with every match replaced by the replacement. This method is one of the most powerful and frequently used string manipulation tools in Ruby.

You will usually reach for gsub when a single substitution is not enough. It works well for cleanup, formatting, and small parsing jobs where the same pattern appears many times in one string.

Syntax

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

Parameters

ParameterTypeDefaultDescription
patternString or RegexpThe substring or pattern to find and replace
replacementString, Hash, or nilThe replacement text, hash of substitutions, or nil when using a block

Examples

Basic string replacement

text = "hello world"
text.gsub("world", "Ruby")
# => "hello Ruby"

This is the simplest form of gsub: a literal string for both the search and the replacement. It replaces every occurrence without needing a regex, which makes the intent obvious at a glance. For one-shot replacements where the target is a fixed substring, this form is the most readable choice.

Replacing all occurrences

text = "hello world hello"
text.gsub("hello", "goodbye")
# => "goodbye world goodbye"

Unlike sub which stops after the first match, gsub continues through the entire string and replaces every occurrence it finds. This global behavior is what makes it the go-to method for cleanup and formatting tasks where you need to change all instances of a pattern — not just the first one.

Using regex patterns

phone = "(555) 123-4567"
phone.gsub(/\(\d{3}\)\s*/, "")
# => "123-4567"

text = "one two three"
text.gsub(/\w+/) { |word| word.upcase }
# => "ONE TWO THREE"

Regex patterns show the full range of this method. You can match complex patterns, capture groups, and apply transformations conditionally — a single regex can express what would take several lines of string scanning. The block form is especially useful when each match needs a slightly different result, because you can inspect the captured text and return a custom replacement for every occurrence. That keeps the code close to the data and avoids a long series of manual replacements.

Using a hash for multiple replacements

replacements = { "cat" => "dog", "run" => "walk" }
"cat run".gsub(/cat|run/, replacements)
# => "dog walk"

The hash form is particularly useful when you need to perform several different substitutions in one pass. Instead of chaining multiple gsub calls — which would scan the string once per pattern — the hash approach matches all alternatives in a single regex alternation and picks the corresponding replacement from the hash. This keeps both the regex and the mapping table in one place, which is easier to maintain when the list of substitutions grows.

Working with capture groups

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

"hello".gsub(/[aeiou]/) { |v| v.upcase }
# => "hEllO"

Common Patterns

Several patterns appear frequently in Ruby code that uses gsub:

  • Find and replace uses a plain string: text.gsub("old", "new").
  • Removing unwanted characters works well with a negated regex: text.gsub(/[^\w]/, "").
  • Collapsing repeated whitespace into a single space: text.gsub(/\s+/, " ").strip.
  • Capture groups let you reorder matched text: text.gsub(/(\w+) (\w+)/, '\2 \1').
  • Transforming each match with a block: text.gsub(/[A-Z]/) { |c| c.downcase }.
  • Stripping non-digit characters from a phone number: phone.gsub(/\D/, '').

Errors

  • No pattern given: Raises ArgumentError if neither pattern nor block is provided.
  • String interpolation in replacement: Remember to escape \1, \2 when using double-quoted strings, or use single quotes.

Practical Notes

gsub always returns a new string, so it is safe when you want to keep the original text unchanged. If you do need to mutate the receiver, Ruby also provides gsub!, which follows the same matching rules but updates the string in place.

When the pattern is broad, test it on a few real inputs before you rely on it. A good regular expression should match the text you want and leave the rest alone. For example, a pattern that strips HTML tags should be verified against actual markup:

html = "<p>Hello <b>world</b></p>"
html.gsub(/<[^>]+>/, '')  # => "Hello world"

See Also