String Methods
Reviewed & published by Brayan K
String methods are the built-in operations Ruby provides for transforming and inspecting text — changing case, trimming whitespace, splitting, searching, and replacing — and they make text wrangling one of Ruby's great pleasures.
Part of the free Ruby course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.
You'll use interpolation, upcase/strip/split/join, gsub, format, and the in-place bang methods like gsub!.
What You'll Learn in This Lesson
- Interpolation and the case methods
- Trimming with strip and chomp
- Splitting and joining with split / join
- Replacing text with gsub and sub
- Searching with include?, start_with?, end_with?
- format / % , chars, bytes, and bang methods
1️⃣ Interpolation, Case & Trimming
Inside double quotes, #{...} drops any expression into a string. The case methods upcase, downcase, capitalize, and swapcase reshape letters, while strip removes surrounding whitespace and chomp removes a trailing newline.
# Interpolation and case methods
name = "ada lovelace"
puts "Hello, #{name.capitalize}!" # only first letter -> "Ada lovelace"
puts name.upcase # ADA LOVELACE
puts name.downcase # ada lovelace
puts "MixedCase".swapcase # mIXEDcASE
puts " spaced ".strip.inspect # "spaced" (trim both ends)
puts "line\n".chomp.inspect # "line" (remove trailing newline)2️⃣ Split, Join & Repeat
split turns a string into an array of pieces (on whitespace by default, or on any delimiter you give it), and join stitches an array back into a string. The * operator repeats a string — handy for separators and banners.
# Splitting, joining, and repeating
csv = "red,green,blue"
parts = csv.split(",") # -> ["red", "green", "blue"]
p parts
puts parts.join(" | ") # red | green | blue
puts "ab" * 3 # ababab (repeat with *)
puts "=" * 10 # ==========
words = "the quick brown fox".split # split on whitespace by default
puts words.length
p words3️⃣ Search, Replace, Format & Bang Methods
Ask questions with include?, start_with?, and end_with?. Replace text with sub (first match) or gsub (all matches), build formatted output with format/%, and reach for a bang method like upcase! when you want to mutate the original string.
# Searching and replacing
text = "I like cats and cats like me"
puts text.include?("cats") # true
puts text.start_with?("I like") # true
puts text.end_with?("me") # true
puts text.gsub("cats", "dogs") # replace ALL: I like dogs and dogs like me
puts text.sub("cats", "dogs") # replace FIRST only
puts "hello world".gsub(/o/, "0") # regex works too: hell0 w0rld# format / %, chars, bytes, and the bang methods
puts format("Pi is %.2f", 3.14159) # Pi is 3.14
puts "Score: %05d" % 42 # Score: 00042
puts "%s is %d" % ["Ada", 36] # Ada is 36
p "café".chars # each character (handles unicode)
p "abc".bytes # the byte values
# Bang methods mutate the string in place and return nil if no change
s = "hello"
s.upcase! # s is now "HELLO"
puts s
result = "HELLO".upcase! # already uppercase -> returns nil
p resultYour turn. Fill in each ___ blank with the right method, then run it.
# 🎯 YOUR TURN — fill in the blanks, then run with: ruby titlecase.rb
title = " the great gatsby "
clean = title.___.split.map(&:capitalize).join(" ") # 👉 trim the outer spaces
puts clean
slug = "Hello World Example".downcase.___(" ", "-") # 👉 replace ALL spaces with -
puts slug
# ✅ Expected output:
# The Great Gatsby
# hello-world-exampleMini-Challenge: Initials & a Censor
Chain split, map, and join to build initials, then use gsub with string repetition to censor a word. Run with ruby strings.rb.
# 🎯 MINI-CHALLENGE: initials and a censor.
# Save as strings.rb and run with: ruby strings.rb
#
# 1. initials(full_name): split on spaces, take the first letter of each
# word, upcase it, join with "." and add a trailing ".".
# "ada lovelace" -> "A.L."
# 2. censor(text, bad): replace every occurrence of "bad" with as many
# "*" as its length, using gsub and "*" * bad.length.
#
# ✅ Example output:
# A.L.
# G.B.M.H.
# this is ***, very ***
# your code hereCommon Errors (and the fix)
- ❌ 'Hi #{name}' printing literally → ✅ interpolation needs double quotes.
- ❌ Expecting capitalize to title-case → ✅ it only uppercases the first letter; split + map for each word.
- ❌ sub when you meant all matches → ✅ use gsub for every occurrence.
- ❌ Chaining on a bang method that returned nil → ✅ use the non-bang version, or store first.
- ❌ "5" + 5 raising a TypeError → ✅ convert: "5" + 5.to_s or interpolate.
Pro Tips
- 💡 Slugify in one line: str.downcase.strip.gsub(/\s+/, "-").
- 💡 tr for swaps: "hello".tr("el", "ip") swaps characters faster than gsub.
- 💡 Frozen by default soon: add # frozen_string_literal: true at the top to make literals immutable and faster.
📋 Quick Reference — String Methods
| Concept | Ruby Syntax |
|---|---|
| Interpolate | "Hi #{name}" |
| Trim / newline | strip , chomp |
| Split / join | split(",") , join("-") |
| Replace all | gsub("a", "b") |
| Contains? | include?("x") |
| Format | format("%.2f", n) |
🎉 Lesson Complete!
- ✅ Interpolation with #{...} in double quotes
- ✅ Case methods, plus strip and chomp
- ✅ split/join convert between strings and arrays
- ✅ gsub replaces all, sub replaces the first
- ✅ format/% for output; bang methods mutate in place
Practice quiz
What does "ada lovelace".capitalize return?
- "Ada Lovelace"
- "ADA LOVELACE"
- "Ada lovelace"
- "ada lovelace"
Answer: "Ada lovelace". capitalize only uppercases the FIRST character of the whole string — it is not title-case.
What is the difference between gsub and sub?
- gsub replaces ALL matches, sub replaces only the FIRST
- No difference
- sub replaces all, gsub the first
- gsub mutates, sub does not
Answer: gsub replaces ALL matches, sub replaces only the FIRST. gsub (global) replaces every match; sub replaces only the first match.
What does "MixedCase".swapcase return?
- "mixedcase"
- "MIXEDCASE"
- "Mixedcase"
- "mIXEDcASE"
Answer: "mIXEDcASE". swapcase flips the case of every letter: upper becomes lower and vice versa.
What does "red,green,blue".split(",") return?
- "red green blue"
- ["red", "green", "blue"]
- ["red,green,blue"]
- 3
Answer: ["red", "green", "blue"]. split breaks the string on the delimiter into an array of pieces.
What does a bang method like upcase! return when it makes NO change?
- nil
- The original string
- An empty string
- false
Answer: nil. A bang method returns the modified string, but returns nil when it changed nothing.
What does "ab" * 3 produce?
- "ab3"
- ["ab", "ab", "ab"]
- "ababab"
- 6
Answer: "ababab". The * operator repeats a string, so "ab" * 3 is "ababab".
What does format("Pi is %.2f", 3.14159) print?
- "Pi is 3.14159"
- "Pi is 3.14"
- "Pi is 3"
- "Pi is 3.1"
Answer: "Pi is 3.14". %.2f formats the float to two decimal places, giving "Pi is 3.14".
Which method removes surrounding whitespace from a string?
- chomp
- trim
- squeeze
- strip
Answer: strip. strip removes whitespace from both ends; chomp only removes a trailing newline.
Interpolation with #{...} works in which kind of string literal?
- Single quotes only
- Double quotes only
- Both single and double quotes
- Neither
Answer: Double quotes only. Interpolation only works in double-quoted strings; single quotes treat #{...} literally.
What does "%05d" % 42 produce?
- "42"
- "42000"
- "00042"
- "5"
Answer: "00042". %05d zero-pads the integer to a width of five characters, giving "00042".
Continue this course
- Previous: Gems & Bundler
- Next: Advanced Enumerable (reduce, group_by, chunk) — reduce, group_by, partition, each_with_object, sort_by, tally
- Quick reference: Ruby cheat sheet › Strings & Symbols
Frequently asked questions
What's the difference between capitalize, upcase, and title-casing?
upcase makes every letter uppercase and downcase makes every letter lowercase. capitalize only uppercases the very first character of the whole string and lowercases the rest — so "hello WORLD".capitalize is "Hello world", not "Hello World". Ruby has no built-in title-case method, so to capitalize each word you split the string, map(&:capitalize) over the words, and join them back with a space, which is exactly the pattern in this lesson's exercise.
When do I use gsub versus sub?
sub replaces only the FIRST match; gsub (the 'g' stands for global) replaces EVERY match. Both accept either a plain string or a regular expression as the pattern, so "a-b-c".gsub("-", "_") and "a1b2".gsub(/\d/, "*") both work. They return a new string and leave the original untouched. Their bang siblings, sub! and gsub!, mutate the receiver in place and return nil if nothing changed.
What do the bang methods like upcase! and gsub! do?
A trailing ! marks a 'dangerous' or mutating version of a method. upcase returns a NEW uppercased string and leaves the original alone; upcase! changes the original string in place. The subtle trap is the return value: a bang method returns the modified string, but returns nil when it made no change — so result = "HELLO".upcase! is nil because the string was already uppercase. Prefer the non-bang version unless you specifically need to mutate the original and avoid allocating a new object.
How do I build strings from values — interpolation or format?
For everyday text, double-quoted interpolation is cleanest: "Hi #{name}, you are #{age}" embeds any expression inside #{...}. When you need precise control over width, padding, or decimals, reach for format (alias sprintf) or the % operator: format("%.2f", pi) rounds to two decimals and "%05d" % 42 zero-pads to five digits. Note that interpolation only works in double-quoted strings; single quotes treat #{...} literally.