Lua non ha un linguaggio regexp convenzionale, ha i modelli Lua al suo posto. Anche se assomigliano molto a regexp, i pattern Lua sono un linguaggio distinto che ha un insieme più semplice di regole e, soprattutto, manca delle funzioni di raggruppamento e di alternanza.
Interpretato come un modello Lua, l'esempio sorprenderà un utente di regexp da molto tempo poiché molti dettagli sono diversi.
I modelli Lua sono describedinPiL e, a prima vista, sono abbastanza simili a una regexp convenzionale per causare confusione. Le maggiori differenze sono probabilmente la mancanza di un operatore alternanza |
, parentesi vengono utilizzati solo per marcare cattura, quantificatori (?
, -
, +
, e *
) si applicano solo a una classe di caratteri o un carattere, e %
è il non carattere di escape \
. Un grande indizio che questo esempio probabilmente non è stato scritto con Lua è la mancanza del modello Lua che cita il carattere %
applicato a qualsiasi (o idealmente, tutti) dei caratteri non alfanumerici nella stringa del modello e all'uso sospetto di \?
che ha l'odore di una normale espressione regolare per abbinare un singolo letterale ?
.
La semplice risposta alla domanda posta è: (^?)*
non è una forma di raccomandata, e sarebbe partita ^*
o *
, catturando la presenza o l'assenza del punto di inserimento. Se questo fosse l'effetto desiderato, allora lo scrivere come (%^?)%*
per renderlo più chiaro.
Per capire perché questo è il caso, prendiamo il modello dato e analizziamolo come un modello Lua. L'intero schema è:
^(^?)*\?(.*)$
consegnato a string.match()
, sarebbe interpretato come segue:
^
ancore la partita all'inizio della stringa.
(
indica l'inizio della prima acquisizione.
^
non è all'inizio del modello o di una classe di caratteri, quindi corrisponde a un carattere letterale ^
. Per chiarezza, è probabile che sia stato scritto come %^
.
?
corrisponde esattamente a zero o a uno dei caratteri precedenti.
)
segna la fine della prima acquisizione.
*
non è dopo qualcosa che può essere quantificato in modo che corrisponda a un letterale *
carattere. Per chiarezza, è probabile che sia stato scritto come %*
.
\
in un modello corrisponde a se stesso, non è un carattere di escape nel linguaggio pattern. Tuttavia, è un carattere di escape in un letterale stringa breve Lua, rendendo il seguente carattere non speciale per il parser letterale stringa che in questo caso è moot perché lo ?
che segue non è stato speciale in ogni caso. Quindi, se il pattern fosse racchiuso tra virgolette doppie o singole, il \
verrebbe assorbito dall'analisi delle stringhe. Se scritto in una lunga serie (come , il backslash sarebbe sopravvissuto il parser di stringa, ad apparire nel modello.
?
partite esattamente zero o uno del carattere precedente.
(
segna l'inizio della seconda acquisizione .
.
corrisponde a qualsiasi carattere a tutti, in modo efficace un sinonimo per la classe [\000-\255]
(ricordate, in Lua fughe numerici sono in decimale non ottale come in C).
*
mat Ches zero o più del personaggio precedente, avidamente.
)
segna la fine della seconda cattura.
$
ancore il modello alla fine della stringa.
in modo che corrisponda e cattura un optional ^
all'inizio della stringa, seguita da *
, quindi un optional \
che non viene catturato, e cattura l'intero resto della stringa. string.match
restituirebbe due stringhe in caso di esito positivo (entrambi o entrambi potrebbero essere di lunghezza zero) o nil
in caso di errore.
Edit: Ho fissato alcuni errori di battitura, e corretto un errore nella mia risposta, notato da Egor in un commento. Ho dimenticato che nei modelli, i simboli speciali perdono la loro particolarità quando si trovano in un punto in cui non può essere applicato. Ciò fa sì che il primo asterisco corrisponda a un asterisco letterale anziché essere un errore. La cascata di quello cade attraverso la maggior parte della risposta.
Si noti che se si desidera veramente una regexp vera in Lua, sono disponibili librerie che la forniranno. Detto questo, il linguaggio di pattern incorporato è piuttosto potente. Se non è sufficiente, potrebbe essere meglio adottare un parser completo e utilizzare LPeg che può fare tutto ciò che può fare un regexp e altro. Viene anche fornito con un modulo che fornisce una sintassi completa delle espressioni regolari che viene tradotta in una grammatica LPeg per l'esecuzione.
Potrebbe specificare il motore regex utilizzato qui? – JaredPar
Lua! http://www.lua.org/pil/20.1.html – doremi
@doremi: Dopo aver letto il documento, la regex di Lua è piuttosto una bestia a parte. Il significato della regex può cambiare se viene usato con gmatch o match. – nhahtdh