String#sub
String#sub replaces the first occurrence of a pattern in a string. It returns a new string and leaves the original unchanged.
Signature
str.sub(pattern, replacement)
str.sub(pattern) { |match| block }
Parameters:
pattern— a String or Regexp to search forreplacement— a String (optional), or a block that returns the replacement
Returns: A new string with the replacement made.
Basic String Replacement
Replace one substring with another:
"hello".sub("l", "x") # => "hexlo"
"hello".sub("lo", "p") # => "help"
Only the first match is replaced:
"hello".sub("l", "x") # => "hexlo" (not "hexxo")
Regexp Patterns
Use a regexp for more control:
"hello123".sub(/\d+/, "world") # => "helloworld"
"hello123".sub(/[aeiou]/, "*") # => "h*llo"
Anchors work as expected:
"hello".sub(/^h/, "H") # => "Hello"
"hello".sub(/o$/, "O") # => "hellO"
Capture Groups
Capture groups let you reuse parts of the matched text:
"hello".sub(/(ello)/, "good-\1") # => "good-ello"
Numbered groups work with backreferences:
"first second".sub(/(\w+) (\w+)/, '\2 \1') # => "second first"
Named capture groups:
"john doe".sub(/(?<first>\w+) (?<last>\w+)/, '\k<last>, \k<first>')
# => "doe, john"
Using a Block
When you pass a block instead of a replacement string, the block receives the match and returns the replacement:
"hello".sub(/[aeiou]/) { |v| v.upcase } # => "hEllo"
This is useful for transformations:
"price: 42".sub(/\d+/) { |n| "$#{n}" } # => "price: $42"
The block gets the full match. Only the first match is replaced.
Special Replacement Patterns
Within a replacement string, these patterns have special meaning:
| Pattern | Meaning |
|---|---|
\& | The entire matched string |
\ | The part before the match |
\' | The part after the match |
\1 \2 | Numbered capture groups |
\\ | A literal backslash |
"hello".sub("l", "(&)") # => "he(l)lo"
"hello".sub("l", "$\`") # => "hehe lo"
"hello".sub("l", "$\'") # => "helo lo"
Deleting Characters
Combine sub with an empty replacement to delete:
"hello!".sub("!", "") # => "hello"
" hello ".sub(" ", "") # => " hello " (only first space)
For deleting all occurrences, use gsub instead.
Comparison with gsub
sub replaces only the first match. gsub replaces all matches:
"hello".sub("l", "x") # => "hexlo"
"hello".gsub("l", "x") # => "hexxo"
See Also
- /reference/string-methods/gsub-bang/ — replace all matches in place
- /reference/string-methods/slice/ — extract substrings by position or pattern