Finding and Extracting Substrings
Apply string.find and string.sub to locate and extract text.
Finding and Extracting Substrings is a free Lua Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
string.find Basics
string.find(s, pattern, init, plain) searches for a pattern in s starting at init (default 1). It returns the start and end positions of the match, or nil if not found. With plain=true, it treats the pattern as a literal string (no magic characters).
local s = "hello world"
local i, j = string.find(s, "world")
print(i, j) -- 7 11
-- Plain search (literal string)
local i2, j2 = string.find("a+b=5", "+", 1, true)
print(i2, j2) -- 2 2
-- Not found
print(string.find(s, "xyz")) -- nilstring.sub for Extraction
string.sub(s, i, j) extracts the substring from position i to j (inclusive). Negative indices count from the end: -1 is the last character. If j is omitted, it defaults to the end of the string.
local s = "hello world"
print(string.sub(s, 1, 5)) -- hello
print(string.sub(s, 7)) -- world
print(string.sub(s, -5)) -- world
print(string.sub(s, 1, -7)) -- hello
print(s:sub(7, 11)) -- world (method syntax)Combining find and sub
Combine string.find and string.sub to locate and extract substrings. First find the delimiter, then extract the parts around it. This is the basic string-splitting approach.
local s = "key=value"
local i = string.find(s, "=")
if i then
local key = string.sub(s, 1, i - 1)
local val = string.sub(s, i + 1)
print(key, val) -- key value
endstring.match for Pattern Capture
string.match(s, pattern, init) returns the captured substrings matching the pattern. If the pattern has no captures, it returns the whole match. If nothing matches, it returns nil. Captures are defined with parentheses in the pattern.
local date = "2024-03-15"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2024 03 15
-- No capture: returns the whole match
local num = string.match("price: 42.5 USD", "%d+%.%d+")
print(num) -- 42.5Finding Last Occurrence
To find the last occurrence of a substring, search with a loop advancing the start position, or search from the end. The standard approach: keep calling string.find with the position just past the previous match until it returns nil.
local function findLast(s, sub)
local last_i, last_j
local i, j = string.find(s, sub, 1, true)
while i do
last_i, last_j = i, j
i, j = string.find(s, sub, j + 1, true)
end
return last_i, last_j
end
local i, j = findLast("a/b/c/d", "/")
print(i, j) -- 6 6Extracting File Extensions
A practical use of string.match: extract the extension from a filename. The pattern "([^%.]+)$" captures the last non-dot sequence at the end of the string, or "%.([^%.]+)$" to capture just after the last dot.
local function getExt(filename)
return string.match(filename, "%.([^%.]+)$")
end
print(getExt("photo.jpg")) -- jpg
print(getExt("archive.tar.gz")) -- gz
print(getExt("README")) -- nil
print(getExt("config.lua.bak")) -- bakSplitting Strings
Lua has no built-in string split, but you can implement one with string.gmatch. Iterate over all non-delimiter sequences or use a pattern that captures between delimiters.
local function split(s, sep)
local result = {}
local pattern = "([^" .. sep .. "]+)"
for part in string.gmatch(s, pattern) do
result[#result+1] = part
end
return result
end
local parts = split("one,two,three,four", ",")
for i, p in ipairs(parts) do
print(i, p)
end
-- 1 one 2 two 3 three 4 fourTrimming Whitespace
Remove leading and trailing whitespace by matching and discarding it. The pattern "^%s*(.-)%s*$" uses a lazy quantifier .- to capture the minimal content between optional leading/trailing spaces.
local function trim(s)
return string.match(s, "^%s*(.-)%s*$")
end
print("|" .. trim(" hello ") .. "|") -- |hello|
print("|" .. trim(" \t\n") .. "|") -- ||
print("|" .. trim("no spaces") .. "|") -- |no spaces|Extracting Numbers from Text
Use string.gmatch with a number pattern to extract all numbers from a string. The pattern %-?%d+%.?%d* matches optional negative sign, digits, optional decimal point, and more digits.
local text = "Revenue: $1,234.56 Expenses: $567.89 Net: $666.67"
local numbers = {}
for n in string.gmatch(text, "%d+%.?%d*") do
numbers[#numbers+1] = tonumber(n)
end
for _, v in ipairs(numbers) do
io.write(v .. " ")
end
print() -- 1 234.0 56.0 567.89 666.67String Position Normalization
Lua's negative indices let you work from the end of a string. string.sub(s, -n) gets the last n characters. Combine with #s to compute positions. Understanding the relationship between positive and negative indices prevents off-by-one bugs.
local s = "abcdefgh"
-- Last 3 characters
print(s:sub(-3)) -- fgh
-- All but last 2
print(s:sub(1, -3)) -- abcdef
-- Character at position from end
print(s:sub(-1, -1)) -- h
print(s:sub(-4, -2)) -- efgQuick Check
What does string.sub("hello", 2, -2) return?
Recap: Finding and Extracting
Summary:
string.find(s, pat, init, plain)— returns start,end or nilstring.sub(s, i, j)— extract by position; negative indices from endstring.match(s, pat)— return captures or full match- Use
plain=truefor literal search (no magic chars) - Implement split with
string.gmatch - Trim:
"^%s*(.-)%s*$"pattern
Frequently asked questions
Is the “Finding and Extracting Substrings” lesson free?
Yes — the full text of “Finding and Extracting Substrings” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.
What will I learn in “Finding and Extracting Substrings”?
Apply string.find and string.sub to locate and extract text. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Finding and Extracting Substrings” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- String Basics: Concat and Length
- Finding and Extracting Substrings
- string.format for Output
- string.gsub and string.gmatch