Reading — step 1 of 5
Learn
~2 min readSandboxing and Embedding
Lua doesn't have full regex — it has its own pattern syntax. Smaller, faster, less expressive.
Character classes:
%a— letters%d— digits%s— whitespace%w— alphanumeric%p— punctuation%l/%u— lower / upper case%c— control characters
Uppercase versions are negation: %A = non-letter.
Quantifiers (more limited than regex):
*— 0 or more (greedy)+— 1 or more (greedy)-— 0 or more (NON-greedy)?— 0 or 1
No {n,m} ranges.
Anchors: ^ start, $ end. Inside [...], ^ means negation.
Captures with ():
local date = "2026-05-08"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2026 05 08
string.gmatch — iterator over all matches:
for word in string.gmatch("the quick brown fox", "%w+") do
print(word)
end
string.gsub — replace (returns new string + count):
local result, n = string.gsub("hello world", "%w+", "X")
print(result, n) -- X X 2
With capture in replacement: %1, %2, ...
string.gsub("hello world", "(%w+)", "<%1>")
-- "<hello> <world>"
Performance tips:
- Lua patterns are MUCH faster than typical regex
- String concatenation
a .. bis O(n+m) every time — for many concats usetable.concat:
local parts = {}
for i = 1, 1000 do
parts[#parts + 1] = tostring(i)
end
local result = table.concat(parts, ",")
- Local variables are MUCH faster than globals — avoid hot-path globals:
local print = print -- cache the global once
for i = 1, n do print(i) end
- Avoid creating tables in tight loops — pre-allocate:
local buf = {}
for i = 1, n do buf[i] = compute(i) end
LuaJIT is dramatically faster than reference Lua for tight numerical code.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…