string.gsub
string.gsub(s, pattern, repl [, n]) string.gsub (global substitute) walks a string, replacing each match of a Lua pattern with repl. It returns the new string and the count of substitutions made. The replacement can be a literal string with %n back-references, a table keyed by capture, or a function called for every match.
Signature
local result, count = string.gsub(s, pattern, repl [, n])
s, the subject string.pattern, a Lua pattern (the same syntaxstring.findandstring.matchaccept).repl, the replacement: a string, a table, or a function.n, optional cap on substitutions. Without it, every match is replaced.
String replacement with back-references
Inside a string repl, %0 is the whole match and %1, %2, … are the captures:
local out, n = string.gsub("hello world", "(%w+) (%w+)", "%2 %1")
print(out, n) --> world hello 1
Use %% to insert a literal percent sign.
Limiting the number of replacements
Pass n to stop after the first few matches:
string.gsub("aaaa", "a", "b", 2) --> "bbaa" 2
Table replacement
When repl is a table, the first capture (or the whole match when there is none) is used as the key. The value becomes the replacement. A nil or false value leaves the match untouched.
local vars = {name = "Ada", role = "engineer"}
local tmpl = "Hello ${name}, you are a ${role}."
print((tmpl:gsub("%${(%w+)}", vars)))
-- Hello Ada, you are a engineer.
Function replacement
When repl is a function, it’s called for each match with the captures (or the whole match) as arguments. The return value is converted to a string and used as the replacement. nil or false keeps the original match.
local function upper_word(w) return w:upper() end
print((string.gsub("hello world", "%w+", upper_word)))
-- HELLO WORLD
This is the cleanest way to do per-match transformations:
local function envvar(name)
return os.getenv(name) or ""
end
local cmd = "deploy ${HOME}/app"
print((cmd:gsub("%${(%w+)}", envvar)))
-- deploy /home/ada/app
Method syntax
("text"):gsub(...) is the same as string.gsub("text", ...):
local trimmed = (" hello "):gsub("^%s+", ""):gsub("%s+$", "")
Note that gsub returns two values; if you chain with :gsub(...) again on the result, wrap in parentheses or capture both returns.
Capture replacement gotchas
%0is the entire match , handy when you want to keep the match and wrap it.%1through%9reference captures; if you write%2but only have one capture, Lua raises an error.- The replacement string is not a regex, so
\nis just two characters; use"\n"(Lua escape) for a newline.
Counting without replacing
Because gsub returns the substitution count as its second value, it doubles as a match counter:
local _, vowels = ("supercalifragilistic"):gsub("[aeiou]", "")
print(vowels) --> 8
See also
- /reference/string-methods/ref-string-find/ , locate a single match.
- /tutorials/strings-and-patterns/ , the tutorial that walks through Lua patterns.
- /guides/lua-string-patterns/ , patterns reference with anchors, classes, and captures.