String Library and Patterns

14.1 Lua Patterns (Not Regular Expressions!)

Letters / non-letters Digits / non-digits Lowercase / uppercase letters Whitespace / non-whitespace Alphanumerics / non-alphanumerics

Printable characters except space (5.2+) Escape (%., %%, %() [set] / [^set] Character class ([%w_], [a-f])

0+ greedy / 1+ greedy / 0+ lazy / optional Capture; () captures the position Back-reference to a capture Balanced match (e.g., %b(), %b{})

Frontier pattern (word boundaries: %f[%w]) There's no alternation (|) and quantifiers apply only to single character classes (not groups). For more power, use LPeg or lrexlib (PCRE bindings).

14.2 String Functions with Patterns

local s = "Date: 2025-10-24, Time: 10:30"

print(s:find("%d+"))                          --> 7  10
print(s:find("2025", 1, true))                --> plain search (no patterns)
print(s:match("(%d+)-(%d+)-(%d+)"))           --> 2025  10  24
local y, m, d = s:match("(%d+)-(%d+)-(%d+)")

for k, v in ("a=1, b=2, c=3"):gmatch("(%w+)=(%w+)") do print(k, v) end

print(("hello world"):gsub("o", "0"))         --> hell0 w0rld  2 (returns the count too)
print(("hello world"):gsub("o", "0", 1))      --> limit replacements
print(("hello world"):gsub("(%w+)", "<%1>"))  --> <hello> <world>
print(("hello world"):gsub("%w+", string.upper))           --> function replacement
print(("$name is $age"):gsub("%$(%w+)", {name = "Ana", age = 30}))   --> table replacement
print(("  trim me  "):match("^%s*(.-)%s*$"))  --> "trim me"

-- Split a string
local function split(str, sep)
    local out = {}
    for piece in (str .. sep):gmatch("(.-)" .. sep:gsub("%p", "%%%0")) do out[#out + 1] = piece end
    return out
end
print(table.concat(split("a,b,,c", ","), "|"))    --> a|b||c

-- Escape magic characters for use in patterns
local function escape_pattern(str) return (str:gsub("[%^%$%(%)%%%.%[%]%*%+%-%?]", "%%%0
…

14.3 string.format, pack and unpack

print(string.format("%5.2f|%-8s|%03d|%x|%X|%o|%e|%g|%c|%q", 3.14159, "left", 7, 255, 255, 8, 12345.678, 0.0001, 65, "a\nb"))
print(string.format("%s %s", 1, true))      -- %s calls tostring (and __tostring)

-- Binary packing (5.3+)
local packed = string.pack("<i4 d z", 42, 3.14, "hi")   -- little-endian int32, double, zero-terminated string
local n, f, str = string.unpack("<i4 d z", packed)
print(#packed, n, f, str)
print(string.packsize("i4 i8"))

14.4 LPeg (Parsing Expression Grammars)

local lpeg = require("lpeg")            -- luarocks install lpeg
local P, R, S, C, Ct = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct
local digit  = R("09")
local number = C(P("-")^-1 * digit^1) / tonumber
local space  = S(" \t")^0
local list   = Ct(number * (space * P(",") * space * number)^0)
local t = list:match("1, -2, 30")       --> {1, -2, 30}
-- re module: regex-like syntax on top of LPeg
local re = require("re")
print(re.match("hello world", "{%a+} ' ' {%a+}"))   --> hello  world