Lua
Pattern matching
Ricerca…
Sintassi
string.find (str, pattern [, init [, plain]]) - Restituisce l'indice di inizio e di fine della corrispondenza in str
string.match (str, pattern [, index]) - Corrisponde a un pattern una volta (iniziando dall'indice)
string.gmatch (str, pattern) - Restituisce una funzione che scorre attraverso tutte le corrispondenze in str
string.gsub (str, pattern, repl [, n]) - Sostituisce sottostringhe (fino ad un massimo di n volte)
.
rappresenta tutti i personaggi%a
rappresenta tutte le lettere%l
rappresenta tutte le lettere minuscole%u
rappresenta tutte le lettere maiuscole%d
rappresenta tutte le cifre%x
rappresenta tutte le cifre esadecimali%s
rappresenta tutti i caratteri degli spazi bianchi%p
rappresenta tutti i caratteri di punteggiatura%g
rappresenta tutti i caratteri stampabili tranne lo spazio%c
rappresenta tutti i caratteri di controllo[set]
rappresenta la classe che è l'unione di tutti i caratteri nel set.[^set]
rappresenta il complemento del set*
partita avida 0 o più occorrenze della precedente classe di caratteri+
partita avida 1 o più occorrenze della precedente classe di personaggi-
Lazy match 0 o più occorrenze della precedente classe di caratteri?
corrisponde esattamente a 0 o 1 occorrenza della precedente classe di caratteri
Osservazioni
In alcuni esempi, viene usata la notazione (<string literal>):function <string literal>
, che è equivalente a string.function(<string literal>, <string literal>)
perché tutte le stringhe hanno una metatable con il __index
campi __index
alla tabella delle string
.
Abbinamento modello Lua
Invece di usare espressioni regolari, la libreria di stringhe Lua ha un set speciale di caratteri usati nelle corrispondenze di sintassi. Entrambi possono essere molto simili, ma la corrispondenza del modello Lua è più limitata e ha una sintassi diversa. Ad esempio, la sequenza di caratteri %a
corrisponde a qualsiasi lettera, mentre la sua versione maiuscola rappresenta tutti i caratteri non lettere , tutte le classi di caratteri (una sequenza di caratteri che, come modello, può corrispondere a un insieme di elementi) sono elencate di seguito.
Classe di carattere | Sezione corrispondente |
---|---|
%un | lettere (AZ, az) |
% c | caratteri di controllo (\ n, \ t, \ r, ...) |
% d | cifre (0-9) |
l% | lettera minuscola (az) |
% p | caratteri di punteggiatura (!,?, &, ...) |
%S | personaggi spaziali |
% u | lettere maiuscole |
% w | caratteri alfanumerici (AZ, az, 0-9) |
%X | cifre esadecimali (\ 3, \ 4, ...) |
% z | il personaggio con rappresentazione 0 |
. | Corrisponde a qualsiasi personaggio |
Come accennato in precedenza, qualsiasi versione maiuscola di quelle classi rappresenta il complemento della classe. Ad esempio, %D
corrisponderà a qualsiasi sequenza di caratteri non a cifre:
string.match("f123", "%D") --> f
Oltre alle classi di caratteri, alcuni personaggi hanno funzioni speciali come modelli:
( ) % . + - * [ ? ^ $
Il carattere %
rappresenta un carattere di escape, facendo %?
corrisponde a un interrogatorio e %%
corrisponde al simbolo percentuale. È possibile utilizzare il carattere %
con qualsiasi altro carattere non alfanumerico, pertanto, se è necessario sfuggire, ad esempio, un preventivo, è necessario utilizzare \\
before it, che sfugge a qualsiasi carattere da una stringa lua.
Un set di caratteri, rappresentato all'interno di parentesi quadre ( []
), ti consente di creare una speciale classe di caratteri, combinando diverse classi e singoli caratteri:
local foo = "bar123bar2341"
print(foo:match "[arb]") --> b
Puoi ottenere il complemento del set di caratteri avviandolo con ^
:
local foo = "bar123bar2341"
print(string.match(foo, "[^bar]")) --> 1
In questo esempio, string.match
troverà la prima volta in cui non è B, una o r.
I pattern possono essere più utili con l'aiuto della ripetizione / modificatori opzionali, i pattern in lua offrono questi quattro caratteri:
Personaggio | Modificatore |
---|---|
+ | Una o più ripetizioni |
* | Zero o più ripetizioni |
- | Anche zero o più ripetizioni |
? | Opzionale (zero o una ricorrenza) |
Il carattere +
rappresenta uno o più caratteri corrispondenti nella sequenza e restituirà sempre la sequenza abbinata più lunga:
local foo = "12345678bar123"
print(foo:match "%d+") --> 12345678
Come puoi vedere, *
è simile a +
, ma accetta zero occorrenze di caratteri ed è comunemente usato per abbinare spazi opzionali tra diversi modelli.
Il carattere -
è simile a *
, ma invece di restituire la sequenza abbinata più lunga, corrisponde a quella più corta.
Il modificatore ?
corrisponde a un carattere opzionale, consentendo di associare, ad esempio, una cifra negativa:
local foo = "-20"
print(foo:match "[+-]?%d+")
Il motore di corrispondenza del modello Lua fornisce alcuni elementi di corrispondenza del modello aggiuntivi:
Oggetto personaggio | Descrizione |
---|---|
%n | per n tra 1 e 9 corrisponde una sottostringa uguale alla n-esima stringa catturata |
%bxy | confronta la sottostringa tra due caratteri distinti (coppia bilanciata di x y ) |
%f[set] | motivo di frontiera: corrisponde a una stringa vuota in qualsiasi posizione in modo tale che il carattere successivo appartiene all'insieme e il personaggio precedente non appartiene all'insieme |
string.find (Introduzione)
La funzione di find
Per prima cosa diamo un'occhiata alla funzione string.find
in generale:
La funzione string.find (s, substr [, init [, plain]])
restituisce l'indice iniziale e finale di una sottostringa, se trovata, e nil altrimenti, a partire dall'indice init
se viene fornito (il valore predefinito è 1).
("Hello, I am a string"):find "am" --> returns 10 11
-- equivalent to string.find("Hello, I am a string", "am") -- see remarks
Presentazione dei modelli
("hello world"):find ".- " -- will match characters until it finds a space
--> so it will return 1, 6
Tutti tranne i seguenti caratteri si rappresentano ^$()%.[]*+-?)
. Ognuno di questi personaggi può essere rappresentato da una %
segue il carattere stesso.
("137'5 m47ch s0m3 d1g175"):find "m%d%d" -- will match an m followed by 2 digit
--> this will match m47 and return 7, 9
("stack overflow"):find "[abc]" -- will match an 'a', a 'b' or a 'c'
--> this will return 3 (the A in stAck)
("stack overflow"):find "[^stack ]"
-- will match all EXCEPT the letters s, t, a, c and k and the space character
--> this will match the o in overflow
("hello"):find "o%d?" --> matches o, returns 5, 5
("hello20"):find "o%d?" --> matches o2, returns 5, 6
-- the ? means the character is optional
("helllllo"):find "el+" --> will match elllll
("heo"):find "el+" --> won't match anything
("helllllo"):find "el*" --> will match elllll
("heo"):find "el*" --> will match e
("helelo"):find "h.+l" -- + will match as much as it gets
--> this matches "helel"
("helelo"):find "h.-l" -- - will match as few as it can
--> this wil only match "hel"
("hello"):match "o%d*"
--> like ?, this matches the "o", because %d is optional
("hello20"):match "o%d*"
--> unlike ?, it maches as many %d as it gets, "o20"
("hello"):match "o%d"
--> wouldn't find anything, because + looks for 1 or more characters
La funzione `gmatch`
Come funziona
La funzione string.gmatch
richiede una stringa di input e un pattern. Questo schema descrive su cosa effettivamente tornare indietro. Questa funzione restituirà una funzione che in realtà è un iteratore. Il risultato di questo iteratore corrisponderà al modello.
type(("abc"):gmatch ".") --> returns "function"
for char in ("abc"):gmatch "." do
print char -- this prints:
--> a
--> b
--> c
end
for match in ("#afdde6"):gmatch "%x%x" do
print("#" .. match) -- prints:
--> #af
--> #dd
--> #e6
end
Presentazione di catture:
Questo è molto simile alla funzione normale, tuttavia restituirà solo le acquisizioni invece della corrispondenza completa.
for key, value in ("foo = bar, bar=foo"):gmatch "(%w+)%s*=%s*(%w+)" do
print("key: " .. key .. ", value: " .. value)
--> key: foo, value: bar
--> key: bar, value: foo
end
La funzione di gsub
non confondere con la funzione string.sub, che restituisce una sottostringa!
Come funziona
argomento stringa
("hello world"):gsub("o", "0")
--> returns "hell0 w0rld", 2
-- the 2 means that 2 substrings have been replaced (the 2 Os)
("hello world, how are you?"):gsub("[^%s]+", "word")
--> returns "word word, word word word?", 5
("hello world"):gsub("([^%s])([^%s]*)", "%2%1")
--> returns "elloh orldw", 2
argomento della funzione
local word = "[^%s]+"
function func(str)
if str:sub(1,1):lower()=="h" then
return str
else
return "no_h"
end
end
("hello world"):gsub(word, func)
--> returns "hello no_h", 2
argomento della tabella
local word = "[^%s]+"
sub = {}
sub["hello"] = "g'day"
sub["world"] = "m8"
("hello world"):gsub(word, sub)
--> returns "g'day m8"
("hello world, how are you?"):gsub(word, sub)
--> returns "g'day m8, how are you?"
-- words that are not in the table are simply ignored