Skip to content

Lua Strings Guide — Pattern Matching and String Manipulation

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Lua Strings Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Lua strings are immutable sequences of bytes with extensive manipulation functions in the string library -- including pattern matching that's simpler than full regex but powerful enough for most text processing tasks.

What You'll Learn

  • Creating and manipulating strings
  • String library functions: sub, upper, lower, rep, reverse
  • Lua pattern matching with character classes and captures
  • Common pattern matching patterns

Creating Strings

local s1 = 'single quotes'
local s2 = "double quotes"
local s3 = [[multi-line
literal string]]
local s4 = "Escaped: \n \t \\"

String Library Functions

local s = "Hello, Lua!"

-- Length
print(#s)  --> 11

-- Case
print(string.upper(s))  --> HELLO, LUA!
print(string.lower(s))  --> hello, lua!

-- Substring (1-indexed)
print(string.sub(s, 1, 5))   --> Hello
print(string.sub(s, 8))      --> Lua!
print(string.sub(s, -4))     --> Lua! (negative = from end)

-- Repetition
print(string.rep("ha", 3))  --> hahaha

-- Reverse
print(string.reverse("Lua"))  --> auL

-- Finding
local start, finish = string.find(s, "Lua")
print(start, finish)  --> 8    10

Pattern Matching

Lua patterns are simpler than regex but use similar concepts.

Character Classes

-- %a = letters, %d = digits, %s = whitespace
-- %l = lowercase, %u = uppercase
-- %w = alphanumeric, %p = punctuation
-- %c = control chars, %x = hex digits
-- . = any character

local text = "Hello 123 World!"

-- Find first digit
print(string.find(text, "%d"))  --> 7    7

-- Find all letters
for word in string.gmatch(text, "%a+") do
    print(word)
end

Pattern Modifiers

-- + = one or more
-- * = zero or more
-- - = zero or more (non-greedy)
-- ? = zero or one
-- ^ = start anchor
-- $ = end anchor

local text = "The quick brown fox"

-- Match words
for w in string.gmatch(text, "%a+") do
    print(w)  --> The, quick, brown, fox
end

-- Anchored match
print(string.find("hello", "^h"))    --> 1    1
print(string.find("hello", "o$"))    --> 5    5
print(string.find("hello", "^x"))    --> nil

Captures

local text = "Name: Alice, Age: 30"

-- Capture with parentheses
local name, age = string.match(text, "Name: (%a+), Age: (%d+)")
print(name)  --> Alice
print(age)   --> 30

-- Multiple captures from gmatch
local csv = "one,two,three"
for a, b, c in string.gmatch(csv, "(%w+),(%w+),(%w+)") do
    print(a, b, c)  --> one    two    three
end

gsub -- Global Substitution

local s = "hello world hello lua"

-- Simple replacement
local result, count = string.gsub(s, "hello", "hi")
print(result)  --> hi world hi lua
print(count)   --> 2

-- Replacement with captures
local result = string.gsub("hello world", "(%w+)", function(w)
    return string.upper(w)
end)
print(result)  --> HELLO WORLD

-- Remove non-alphanumeric
local clean = string.gsub("Hello, World! #2024", "%W", "")
print(clean)  --> HelloWorld2024

Common Patterns

-- Email extraction
local text = "Contact: user@example.com or admin@test.org"
for email in string.gmatch(text, "[%w.%-]+@[%w.%-]+%.%w+") do
    print(email)
end

-- URL parsing
local url = "https://example.com/path?key=value"
local _, _, protocol, host, path = string.find(url,
    "(https?)://([^/]+)(/.*)")
print(protocol)  --> https
print(host)      --> example.com
print(path)      --> /path?key=value

-- Strip HTML tags
local html = "<b>Bold</b> and <i>italic</i>"
local plain = string.gsub(html, "<[^>]+>", "")
print(plain)  --> Bold and italic

Common Mistakes

1. Confusing Lua patterns with regex

Lua patterns are not full regex. There's no alternation |, no lookahead, no non-capturing groups. Use LPeg for complex patterns.

2. Forgetting to escape magic characters

Magic characters in Lua patterns: ( ) . % + - * ? [ ] ^ $. Use % to escape them: %. matches literal dot.

3. Using % instead of %%

To match a literal %, use %%. % is always an escape prefix.

4. Expecting Unicode support in patterns

Lua patterns work on bytes, not characters. For Unicode, use libraries like lua-unidecode.

5. Not anchoring patterns

Unanchored patterns match anywhere in the string. Use ^ and $ to anchor.

Practice Questions

1. How do you find all occurrences of a pattern in a string? Use string.gmatch(s, pattern) which returns an Iterator. Or string.find in a loop.

2. What is the difference between + and - in patterns? + matches one or more (greedy, captures as many as possible). - matches zero or more (non-greedy, captures as few as possible).

3. How do you escape a magic character in a Lua pattern? Prepend with %: %. matches a literal dot, %% matches a literal percent sign.

Challenge: Write a function extract_emails(text) that returns a table of all email addresses found in the input text.

FAQ

{{< faq question="Are Lua patterns as powerful as regex?" >}} No. Lua patterns are simpler and intentionally less powerful. They lack alternation, lookahead/lookbehind, and backreferences. For complex patterns, use LPeg (a PEG Parsing library). {{< /faq >}}

{{< faq question="Are Lua strings mutable?" >}} No. All string operations return new strings. Lua handles this efficiently through internal string interning. {{< /faq >}}

{{< faq question="How do I check if a string contains a substring?" >}} Use string.find(s, substring). If it returns non-nil, the substring exists. Or use s:find(substring) with the colon syntax. {{< /faq >}}

{{< faq question="What is the maximum string length?" >}} The theoretical limit is the Lua memory limit. In practice, strings up to several hundred MB work, but very large strings cause GC pauses. {{< /faq >}}

{{< faq question="How do I convert a string to lowercase?" >}} string.lower(s) or s:lower(). For case-insensitive comparison, compare s:lower() or use string.find(s, pattern, 1, true) for literal matches. {{< /faq >}}

What's Next

Now that you understand strings, learn about numbers and the math library.

Topic Description Link
Numbers Arithmetic, math library, precision {{< ref "15-numbers" >}}
Booleans Truthiness and logical operators {{< ref "16-booleans" >}}
Python Compare with Python strings Python

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro