2013-03-04 21 views
18

Ho questa regex:Cosa significa (^?) * In questa regex?

^(^?)*\?(.*)$ 

Se ho capito bene, questa è la ripartizione di ciò che fa:

  • ^- inizio corrispondente dall'inizio della stringa
  • (^?) * - Non lo so, ma lo memorizza in $ 1
  • \? - corrisponde un punto interrogativo
  • $ (*.) - corrisponde a qualsiasi cosa fino alla fine della stringa

Così che cosa (^?) * Significa?

+0

Potrebbe specificare il motore regex utilizzato qui? – JaredPar

+0

Lua! http://www.lua.org/pil/20.1.html – doremi

+1

@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

risposta

20

Il (^?) sta semplicemente cercando il carattere letterale ^. Il carattere ^ in uno schema regex ha un significato speciale solo se utilizzato come primo carattere del pattern o come primo carattere in una corrispondenza di raggruppamento []. Quando usato fuori quei 2 posizioni ^ viene interpretato letteralmente nel look per il carattere ^ nella stringa di input

Nota: Se o non ^ esterna della prima e raggruppamento posizione viene interpretato letteralmente è regex specifico motore. Non ho familiarità con LUA per stabilire quale sia

+0

Hmm. Ancora non capisco. Puoi darmi un esempio di una stringa in cui questo corrisponderebbe? Cordiali saluti - questo viene utilizzato su un URL con una stringa di query. – doremi

+2

nessun commento sull'inutilità di '(^?) *'? cioè è una corrispondenza di 0 o un carattere, corrispondente solo al carattere '^', corrispondente a 0 a molte volte - lo stesso (probabilmente) come '(^ *)' a meno che non vengano utilizzati più gruppi – AD7six

+0

Potrebbe essere una cattiva espressione regolare come mi avrebbe fornito da qualcun altro. Questo è parte del motivo per cui sto cercando di capire cosa fa. – doremi

2

In questo caso, il (^?) Si riferisce alla stringa precedente "^" che indica il carattere letterale^come ha detto Jared. Controlla regexlib per ulteriori decifrazioni.

Per tutte le Regex esigenze: http://regexlib.com/CheatSheet.aspx

1

Sembra a me come l'intento del creatore del espressione era per adattarsi a qualsiasi numero di^prima del punto di domanda, ma ha voluto solo per cattura prima istanza di ^. Tuttavia, potrebbe non essere un'espressione valida a seconda del motore, come altri hanno affermato.

6

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.

+0

In realtà, il primo '*' non è un errore, è semplicemente privo di magia. Ad esempio, 'assert (string.match ("^* ","^(^?) * "))' –

+0

@EgorSkriptunoff Penso che tu abbia ragione. L'effetto è più o meno lo stesso, il pattern non corrisponde a quello che un utente di espressioni regolari pensa che corrisponderebbe. – RBerteig

Problemi correlati