Pattern Matching in Lua
Il pattern matching in Lua e un sistema potente per cercare, estrarre e manipolare testo. Lua non utilizza le espressioni regolari tradizionali, ma implementa un proprio sistema di pattern piu leggero e semplice, pur essendo efficace per la maggior parte delle operazioni comuni.
Classi di Caratteri
Ogni classe e rappresentata da % seguito da una lettera. La versione maiuscola rappresenta il complemento:
| Classe | Significato | Complemento |
|---|---|---|
%a |
Lettere (a-z, A-Z) | %A non-lettere |
%d |
Cifre (0-9) | %D non-cifre |
%l |
Lettere minuscole | %L non-minuscole |
%u |
Lettere maiuscole | %U non-maiuscole |
%s |
Spazi bianchi | %S non-spazi |
%p |
Punteggiatura | %P non-punteggiatura |
%w |
Alfanumerici | %W non-alfanumerici |
%c |
Caratteri di controllo | %C non-controllo |
local testo = "Lua 5.4 nel 2026"
print(string.find(testo, "%d")) -- 5 5 (prima cifra)
print(string.find(testo, "%a")) -- 1 1 (prima lettera)
Il punto . corrisponde a qualsiasi carattere. Per cercare caratteri speciali letterali si usa %:
print(string.find("versione 5.4", "5%.4")) -- 10 12
print(string.find("sconto 50%", "%%")) -- 10 10
Insiemi di Caratteri e Modificatori
Gli insiemi tra [] corrispondono a uno dei caratteri elencati. Con ^ all’inizio si ottiene il complemento:
print(string.find("ciao", "[aeiou]")) -- 2 2 (la "i")
print(string.find("abc123", "[^%a]")) -- 4 4 (primo non-lettera)
I modificatori di quantita specificano le ripetizioni:
| Modificatore | Significato |
|---|---|
+ |
Una o piu ripetizioni (greedy) |
* |
Zero o piu ripetizioni (greedy) |
- |
Zero o piu ripetizioni (lazy) |
? |
Zero o una occorrenza |
print(string.find("Il numero 12345", "%d+")) -- 11 15
-- Differenza tra greedy e lazy
local html = "<b>grassetto</b>"
print(string.match(html, "<.+>")) -- <b>grassetto</b> (greedy)
print(string.match(html, "<.->")) -- <b> (lazy)
print(string.match("color", "colou?r")) -- color
print(string.match("colour", "colou?r")) -- colour
Ancore
Le ancore ^ e $ vincolano il pattern all’inizio o alla fine della stringa:
print(string.find("Lua e bello", "^Lua")) -- 1 3
print(string.find("Lua e bello", "bello$")) -- 7 11
print(string.find("12345", "^%d+$")) -- 1 5 (solo cifre)
print(string.find("123a5", "^%d+$")) -- nil
string.match: Estrarre Corrispondenze
Restituisce le porzioni che corrispondono al pattern. Con catture (), restituisce le catture:
print(string.match("oggi 08/02/2026", "%d+")) -- 08
local g, m, a = string.match("08/02/2026", "(%d+)/(%d+)/(%d+)")
print(g, m, a) -- 08 02 2026
local utente, dominio = string.match("info@esempio.com", "(%w+)@(%w+%.%w+)")
print(utente, dominio) -- info esempio.com
string.gmatch: Iterare sulle Corrispondenze
Restituisce un iteratore che produce tutte le corrispondenze successive:
-- Trovare tutte le parole
for parola in string.gmatch("Lua e potente", "%a+") do
io.write(parola .. " ")
end -- Lua e potente
-- Estrarre coppie chiave-valore
local config = "nome=Mario eta=30 citta=Roma"
for chiave, valore in string.gmatch(config, "(%w+)=(%w+)") do
print(chiave .. " -> " .. valore)
end
-- Raccogliere numeri in una tabella
local numeri = {}
for n in string.gmatch("10, 20, 30", "%d+") do
table.insert(numeri, tonumber(n))
end
string.gsub con Pattern
Sostituisce le occorrenze di un pattern. Accetta anche una funzione come sostituzione:
-- Rimuovere spazi multipli
print(string.gsub(" Ciao mondo ", "%s+", " "))
-- Funzione trim
local function trim(s)
return s:gsub("^%s+", ""):gsub("%s+$", "")
end
print("[" .. trim(" ciao ") .. "]") -- [ciao]
-- Sostituzione con funzione: raddoppia i numeri
print(string.gsub("ho 3 gatti e 2 cani", "%d+", function(n)
return tostring(tonumber(n) * 2)
end)) -- ho 6 gatti e 4 cani
-- Capitalizzare ogni parola
print(string.gsub("ciao mondo", "(%a)(%a*)", function(prima, resto)
return prima:upper() .. resto:lower()
end)) -- Ciao Mondo
Esempio Pratico: Validazione Email
local function valida_email(email)
return string.match(email, "^[%w%.%-_]+@[%w%.%-]+%.%a%a+$") ~= nil
end
print(valida_email("utente@esempio.com")) -- true
print(valida_email("senza-chiocciola.com")) -- false
Conclusioni
Il pattern matching di Lua, pur essendo piu semplice delle espressioni regolari tradizionali, e efficace per la maggior parte delle operazioni sul testo. Le classi di caratteri, i modificatori, le ancore e le catture forniscono strumenti potenti. Le funzioni string.find, string.match, string.gmatch e string.gsub costituiscono un toolkit completo per lavorare con i pattern.