Replacing Text

The method gsub (global substitution) replaces every part of a text that fits a pattern with another text. Like the other string functions, it doesn't change the original; it gives a new text. And it gives one more value: how many replacements it made.

local note = "Fresh eggs, fresh milk"
print(note:gsub("fresh", "FRESH"))

This prints:

Fresh eggs, FRESH milk	1

Only one replacement: Fresh with a capital F is a different text. And after a tab, there's the count, because print prints every value it gets. Most of the time, you want just the text. There are three ways to get it:

local note = "Fresh eggs, fresh milk"
print((note:gsub("eggs", "honey")))
local better = note:gsub("milk", "cheese")
print(better)
local loud, count = note:gsub("fresh", "FRESH")
print(loud, count)

This prints:

Fresh honey, fresh milk
Fresh eggs, fresh cheese
Fresh eggs, FRESH milk	1

Extra parentheses around a call keep only its first value. One variable keeps only the first value too, and with two variables, you get both. The parentheses really matter when you pass the result to another function, which would get the count as one more argument. The second argument of tonumber is the base of the number (10 for ordinary numbers), so this ends with an error:

local weight = "12 kg"
print(tonumber(weight:gsub(" kg", "")))
main.lua:2: bad argument #2 to 'tonumber' (base out of range)

With tonumber((weight:gsub(" kg", ""))), it works.

The first argument is a pattern, so everything from the last two exercises works in it. To remove something, replace it with an empty text, "". To squash runs of spaces, replace %s+ with a single space:

local note = "Eggs:  12,   milk: 18"
print((note:gsub("%s+", " ")))
print((note:gsub("%d", "?")))

This prints:

Eggs: 12, milk: 18
Eggs:  ??,   milk: ??

Because it's a pattern, watch out for magic characters. Many countries write decimal numbers with a comma, but replacing "." replaces every character, because the dot means any character. %. is the period itself:

print(("3.50"):gsub(".", ","))
print(("3.50"):gsub("%.", ","))

This prints:

,,,,	4
3,50	1

In the replacement text, % is special too: %1 puts in what the first capture found, %2 the second, and so on. This turns a date around:

local date = "2026-06-14"
print((date:gsub("(%d+)-(%d+)-(%d+)", "%2/%3/%1")))

This prints:

06/14/2026

The count is useful on its own, too. To find out how many times a word is in a text, replace it with itself and keep only the count: local _, times = note:gsub("eggs", "eggs").

Instructions

Grandpa Joe can't spell potatoes. With gsub, replace every potatos with potatoes, and print the fixed note, without the count:

Fresh potatoes and eggs!   Big potatoes   for 3 coins.

Print how many words you fixed, with the second value of gsub: Fixed: 2.

The note also has too many spaces. In the fixed note, replace every run of spaces with a single space, and print the clean note:

Fresh potatoes and eggs! Big potatoes for 3 coins.

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

8/9