Skip to content
AgileLogics
6 min read

String Patterns

Prerequisites: String functions

Lua doesn't include regular expressions — the whole regex engine would be bigger than Lua itself. Instead it has patterns: simpler, but enough for most text processing.

Character classes

Class Matches
. any character
%a letters
%d digits
%s whitespace
%w letters and digits
%p punctuation
%u / %l upper-case / lower-case letters
%A, %D, ... the complement (not letters, not digits, ...)
[abc], [^abc], [0-9a-f] sets
%. a literal . (% escapes special characters)

Quantifiers: + (one or more), * (zero or more, longest), - (zero or more, shortest), ? (optional). Anchors: ^ start, $ end.

print(("Order 1042 shipped"):match("%d+"))
print(("  padded  "):match("^%s*(.-)%s*$"))
print(("key = value"):match("^(%w+)%s*=%s*(%w+)$"))
print(("<b>bold</b><i>it</i>"):match("<(.-)>"))
print(("<b>bold</b><i>it</i>"):match("<(.*)>"))
print(("2025-04-22"):match("^(%d%d%d%d)%-(%d%d)%-(%d%d)$"))
1042
padded
key	value
b
b>bold</b><i>it</i
2025	04	22
  • Parentheses create captures; match returns them.
  • .- is lazy (shortest), .* greedy (longest) — compare the two tag examples.
  • - is special, so a literal hyphen is %-.

Finding all matches

local text = "Contact ada@example.com or linus@kernel.org"
for user, domain in text:gmatch("([%w%.]+)@([%w%.]+%w)") do
  print(user, domain)
end

local words = {}
for word in ("the cat and the hat"):gmatch("%a+") do
  words[word] = (words[word] or 0) + 1
end
print(words.the, words.cat)
ada	example.com
linus	kernel.org
2	1

Replacing with gsub

print(("hello world"):gsub("o", "0"))
print((("2025-04-22"):gsub("(%d+)-(%d+)-(%d+)", "%3/%2/%1")))
print((("hello world"):gsub("%a+", string.upper)))
print((("$name is $age"):gsub("%$(%w+)", {name = "Ada", age = 36})))
print((("a  b   c"):gsub("%s+", " ")))
hell0 w0rld	2
22/04/2025
HELLO WORLD
Ada is 36
a b c

The replacement can be a string (%1 refers to captures), a function (called with the captures), or a table (looked up by the capture) — the last two make templating trivial.

Limits

Patterns have no alternation (cat|dog) and quantifiers apply only to single characters or classes, not groups. For complex grammars, use the LPeg library. For checking regular expressions in other languages, try the Regex Tester.