Strings and patterns

Lua · Practical · 14 min

Text processing is a daily task, and Lua patterns look like regex but behave differently.

All string functions live in the string table, and strings have it as their metatable, so s:upper() is the same as string.upper(s). The colon passes s as the first argument.

Indexes are 1-based and negative indexes count from the end: s:sub(-3) is the last three bytes. string.format works like C's printf (%d, %5.2f, %s, %q for a quoted literal). s:rep(n), s:reverse() and s:byte()/string.char round out the basics.

Patterns are Lua's lightweight alternative to regular expressions. Classes are written with %: %d digit, %a letter, %s space, %w alphanumeric, and the uppercase version negates. Quantifiers are *, +, ? and - (lazy *). Captures use parentheses. There is no alternation (|) and no {n,m}.

  • s:find(p) returns the start and end index, plus captures.
  • s:match(p) returns the captures (or the whole match).
  • s:gmatch(p) iterates over all matches in a for loop.
  • s:gsub(p, repl) replaces; repl can be a string with %1, a table or a function.

Because % escapes magic characters, write %. for a literal dot. Pass true as the fourth argument of find for a plain substring search.

Strings are bytes: for UTF-8 text use the utf8 library (utf8.len, utf8.codes).

Example

local s = "Lua 5.4 was released in 2020"
print(s:upper():sub(1, 3))           --> LUA
print(s:find("%d+"))                 --> 5	5
print(s:match("(%d+)%.(%d+)"))       --> 5	4

for word in s:gmatch("%a+") do io.write(word, ",") end
print()                              --> Lua,was,released,in,

local out, n = s:gsub("%d+", function(d) return "<" .. d .. ">" end)
print(out, n)  --> Lua <5>.<4> was released in <2020>	3

print(("key = value"):match("^(%w+)%s*=%s*(%w+)$"))  --> key	value
print(string.format("%-5s|%6.2f|%q", "ab", math.pi, "hi")) --> ab   |  3.14|"hi"
print(#"héllo", utf8.len("héllo"))   --> 6	5

Remember

  • s:method() calls string.method(s)
  • Patterns use % classes (%d, %a, %s) and have no alternation
  • gsub accepts a string, table or function as the replacement
  • Use utf8 functions for character counts in UTF-8 text

Watch out for

  • Using . or - unescaped when you mean the literal character; write %. and %-.

Check yourself

  1. What does ("a.b.c"):gsub(".", "-") return as its first value?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.lua.org/manual/5.4/manual.html#6.4.1

Builds on

Unlocks

Nothing builds on this yet.