Quantificatori avidi contro riluttanti contro possessivi


357

Ho trovato questo eccellente tutorial sulle espressioni regolari e mentre capisco intuitivamente cosa fanno i quantificatori "avidi", "riluttanti" e "possessivi", sembra esserci un serio buco nella mia comprensione.

Nello specifico, nell'esempio seguente:

Enter your regex: .*foo  // greedy quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // reluctant quantifier
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // possessive quantifier
Enter input string to search: xfooxxxxxxfoo
No match found.

La spiegazione menziona alimentazione dell'intera stringa di input, lettere state consumate , matcher svitando , occorrenza più a destra di "foo" è stato rigurgitato , etc.

Sfortunatamente, nonostante le belle metafore, non capisco ancora cosa viene mangiato da chi ... Conosci un altro tutorial che spiega (in modo conciso) come funzionano i motori delle espressioni regolari?

In alternativa, se qualcuno può spiegare in modo leggermente diverso il seguente paragrafo, sarebbe molto apprezzato:

Il primo esempio usa il quantificatore avido. * Per trovare "qualsiasi cosa", zero o più volte, seguito dalle lettere "f" "o" "o". Poiché il quantificatore è avido, la porzione. * Dell'espressione mangia prima l'intera stringa di input. A questo punto, l'espressione complessiva non può avere successo, perché le ultime tre lettere ("f" "o" "o") sono già state consumate ( da chi? ). Quindi il matcher indietreggia lentamente ( da destra a sinistra? ) Una lettera alla volta fino a quando l'occorrenza più a destra di "pippo" è stata rigurgitata ( cosa significa? ), A quel punto la partita ha successo e la ricerca termina.

Il secondo esempio, tuttavia, è riluttante, quindi inizia col primo consumo ( da parte di chi? ) "Niente". Poiché "foo" non appare all'inizio della stringa, è costretto a deglutire ( chi deglutisce?) La prima lettera (una "x"), che fa scattare la prima partita a 0 e 4. Il nostro cablaggio di prova continua il processo fino a quando la stringa di input è esaurita. Trova un'altra corrispondenza a 4 e 13.

Il terzo esempio non riesce a trovare una corrispondenza perché il quantificatore è possessivo. In questo caso, l'intera stringa di input viene consumata da. * +, ( How? ) Senza lasciare nulla per soddisfare il "pippo" alla fine dell'espressione. Utilizzare un quantificatore possessivo per le situazioni in cui si desidera cogliere tutto senza mai arretrare ( cosa significa arretrare? ); supererà il quantificatore avido equivalente nei casi in cui la corrispondenza non viene trovata immediatamente.


22
Maximal quantificatori piace *, +e ?sono avidi. Minimal quantificatori piace *?, +?e ??sono pigri. Possessivi quantificatori piace *+, ++e ?+sono appiccicosi.
tchrist,

6
Questa domanda è stata aggiunta alle FAQ sull'espressione regolare di Stack Overflow , in "Quantificatori> Altre informazioni sulle differenze ...".
aliteralmind

Di interesse: i tutorial Java ™ - Differenze tra quantificatori avidi, riluttanti e possessivi - Scorri verso il basso per vedere la sezione.
Guy Coder

Risposte:


495

Ci proverò.

Un quantificatore avido prima corrisponde il più possibile. Quindi .*corrisponde all'intera stringa. Quindi il matcher tenta di abbinare quanto fsegue, ma non sono rimasti caratteri. Quindi "torna indietro", facendo corrispondere al goloso quantificatore un carattere in meno (lasciando la "o" alla fine della stringa senza eguali). Ciò non corrisponde ancora fal regex, quindi fa un passo indietro di un altro passo, facendo in modo che il quantificatore avido abbini di nuovo un carattere in meno (lasciando "oo" alla fine della stringa senza eguali). Questo non corrisponde ancoraf al regex, quindi fa un passo indietro di un altro passo (lasciando il "pippo" alla fine della stringa senza eguali). Ora, il matcher finalmente corrisponde fa nella regex,ooanche abbinati. Successo!

Un quantificatore riluttante o "non avido" prima corrisponde il meno possibile. Quindi all'inizio .*non corrisponde nulla, lasciando l'intera stringa senza eguali. Quindi il matcher tenta di abbinare quanto fsegue, ma la parte ineguagliata della stringa inizia con "x" in modo che non funzioni. Quindi il matcher fa un passo indietro, facendo sì che il quantificatore non avido abbini un altro personaggio (ora corrisponde alla "x", lasciando "fooxxxxxxfoo" senza eguali). Quindi cerca di abbinare il f, che ha successo, e anche il oe il successivo onella regex. Successo!

Nel tuo esempio, ricomincia quindi il processo con la parte rimanente ineguagliata della stringa, "xxxxxxfoo", seguendo lo stesso processo.

Un quantificatore possessivo è proprio come il quantificatore avido, ma non fa marcia indietro. Quindi inizia con la .*corrispondenza dell'intera stringa, senza lasciare nulla di simile. Quindi non c'è più nulla per cui corrispondere a fin nella regex. Dal momento che il quantificatore possessivo non fa marcia indietro, la partita fallisce lì.


15
+1 buona risposta. Vorrei solo aggiungere: vai a leggere Mastering Regular Expressions (3a edizione)
ridgerunner

@ Anomie un po 'in ritardo ma, nella parte possessiva, penso che volevi dire Quindi inizia con .*+ (nota il "+")
RD

3
cosa fa esattamente il quantificatore possessivo? se non corrisponde a questo? (Voglio dire qual è il punto, se non puoi avere personaggi dopo di esso)
ricomincia il

4
@relipse: lo useresti in una situazione in cui sai che il backtracking non ti aiuterà, probabilmente non con .*+quello che corrisponde a tutto. Ad esempio, se si dispone di un modello [xyz]*foo, non è possibile che il backtracking di x, y e z abbinati al [xyz]*bit consentirà mai di abbinare il bit seguente foo, in modo da poter accelerare le cose rendendolo possessivo.
Anomie il

4
@moodboom, ci sono mai zero casi (fatti matematici) in cui quantificatori possessivi produrranno una corrispondenza che non sarà prodotta da semplici quantificatori avidi. Ci sono casi occasionali in cui non produrranno una corrispondenza quando quantificatori avidi produrranno una corrispondenza. Per TUTTI gli altri casi (in cui avidi e possessivi producono gli stessi risultati), i quantificatori possessivi danno un miglioramento delle prestazioni.
Wildcard

49

È solo il mio risultato pratico per visualizzare la scena-

Immagine visiva


3
Tranne che penso che l'ultimo caso, possessivo, non dovrebbe avere n passaggi - basta afferrare l'intera stringa in una volta.
Tratta bene le tue mod

@phyzome Penso che sia ok adesso?
SIslam,

1
Grazie per la spiegazione visiva :)
Lars Moelleken il

In EXPRESSION .*?foo(), i [f] [o] [o]rettangoli non dovrebbero essere gialli in 5th pass?
tonix,

1
@tonix si! La colorazione gialla deve essere eseguita per la parte corrispondente nell'espressione .*?fooe .*+foo.
SIslam,

24

Non ho mai sentito i termini esatti "rigurgitare" o "arretrare" prima; la frase che li sostituirà è "backtracking", ma "rigurgitare" sembra una frase buona come una qualsiasi per "il contenuto che era stato provvisoriamente accettato prima che il backtracking lo gettasse di nuovo".

La cosa importante da capire sulla maggior parte dei motori regex è che stanno facendo un passo indietro : accetteranno provvisoriamente una potenziale, parziale corrispondenza, mentre cercano di abbinare l'intero contenuto della regex. Se il regex non può essere completamente abbinato al primo tentativo, il motore regex tornerà indietro su una delle sue partite. Sarà provare la corrispondenza *, +, ?, alternanza, o {n,m}ripetizione diverso e riprovare. (E sì, questo processo può richiedere molto tempo.)

Il primo esempio usa il quantificatore avido. * Per trovare "qualsiasi cosa", zero o più volte, seguito dalle lettere "f" "o" "o". Poiché il quantificatore è avido, la porzione. * Dell'espressione mangia prima l'intera stringa di input. A questo punto, l'espressione complessiva non può avere successo, perché le ultime tre lettere ("f" "o" "o") sono già state consumate ( da chi? ).

Le ultime tre lettere, f, o, e osono stati già consumati dalla prima .*parte della regola. Tuttavia, l'elemento successivo nella regex fnon ha più nulla nella stringa di input. Il motore sarà costretto a tornare indietro sulla sua .*partita iniziale e provare a far corrispondere il personaggio tutto tranne l'ultimo. (Potrebbe essere intelligente e tornare indietro di tutti, tranne gli ultimi tre, perché ha tre termini letterali, ma non sono a conoscenza dei dettagli di implementazione a questo livello.)

Quindi il matcher indietreggia lentamente ( da destra a sinistra? ) Una lettera alla volta fino a quando l'occorrenza più a destra di "pippo" è stata rigurgitata ( cosa significa? )

Questo significa che l' fooaveva provvisoriamente stati tra quando la corrispondenza .*. Poiché quel tentativo fallito, il motore regex prova ad accettare un carattere in meno in .*. Se ci fosse stato un successo di abbinamento prima che l' .*In questo esempio, il motore sarebbe probabilmente provare a ridurre la .*partita (da destra a sinistra, come lei ha sottolineato, perché è un qualificatore avido), e se era in grado di eguagliare l'intero ingressi, allora potrebbe essere costretto a rivalutare ciò che aveva abbinato prima che il .*mio esempio ipotetico.

indica che la corrispondenza ha esito positivo e la ricerca termina.

Il secondo esempio, tuttavia, è riluttante, quindi inizia col primo consumo ( da parte di chi? ) "Niente". Perché "pippo"

Il nulla iniziale viene consumato da .?*, che consumerà la quantità più breve possibile di tutto ciò che consente al resto del regex di corrispondere.

non appare all'inizio della stringa, è costretto a deglutire ( chi deglutisce?) il

Ancora una volta .?*consuma il primo personaggio, dopo il backtracking sull'incapacità iniziale di abbinare l'intera regex con la corrispondenza più breve possibile. (In questo caso, il motore regex sta estendendo la corrispondenza .*?da sinistra a destra, perché .*?è riluttante.)

prima lettera (una "x"), che attiva la prima corrispondenza a 0 e 4. Il nostro cablaggio di prova continua il processo fino a quando la stringa di input è esaurita. Trova un'altra corrispondenza a 4 e 13.

Il terzo esempio non riesce a trovare una corrispondenza perché il quantificatore è possessivo. In questo caso, l'intera stringa di input viene consumata da. * +, ( Come? )

A .*+consumerà il più possibile e non tornerà indietro per trovare nuove partite quando la regex nel suo insieme non riesce a trovare una corrispondenza. Perché la forma possessiva non esegue il backtracking, probabilmente non vedrete molti usi con .*+, ma piuttosto con classi di personaggi o restrizioni simili: account: [[:digit:]]*+ phone: [[:digit:]]*+.

Questo può accelerare drasticamente la corrispondenza regex, perché stai dicendo al motore regex che non dovrebbe mai tornare indietro su potenziali corrispondenze se un input non corrisponde. (Se dovessi scrivere tutto il codice corrispondente a mano, questo sarebbe simile al non usare mai putc(3)per "respingere" un carattere di input. Sarebbe molto simile al codice ingenuo che si potrebbe scrivere al primo tentativo. Tranne i motori regex sono molto meglio di un singolo carattere di push-back, possono riportare tutto a zero e riprovare. :)

Ma più che potenziali accelerazioni, questo può anche permetterti di scrivere regex che corrispondono esattamente a ciò che devi abbinare. Ho difficoltà a trovare un semplice esempio :) ma scrivere una regex usando quantificatori possessivi e avidi può darti corrispondenze diverse e l'una o l'altra potrebbe essere più appropriata.

senza lasciare nulla per soddisfare il "foo" alla fine dell'espressione. Utilizzare un quantificatore possessivo per le situazioni in cui si desidera cogliere tutto senza mai arretrare ( cosa significa arretrare? ); supererà

"Ritirarsi" in questo contesto significa "tornare indietro": gettare via una partita parziale provvisoria per provare un'altra partita parziale, che potrebbe non riuscire.

il quantificatore avido equivalente nei casi in cui la corrispondenza non viene trovata immediatamente.


2
Ho il sospetto che non ci sia mai un caso in cui un quantificatore possessivo corrisponderà a qualcosa che un avido quantificatore non farà. Credo che lo dimostri quanto segue: un avido quantificatore corrisponde sempre il più possibile, quindi fa un passo indietro se non riesce a trovare una corrispondenza. Un quantificatore possessivo abbina il più possibile, quindi si chiude se non riesce a trovare una corrispondenza. Quindi potrebbe esserci qualcosa a cui un avido quantificatore corrisponde a quello che un quantificatore possessivo non farà, ma non il contrario, poiché entrambi cercano "l'albero" nella stessa sequenza, il quantificatore possessivo si arrende più facilmente. ;)
Wildcard

2
Confermato: "Ecco a cosa servono il raggruppamento atomico e i quantificatori possessivi: efficienza impedendo il backtracking". da regular-expressions.info Quindi l'affermazione in questa risposta "Ma più che potenziali accelerazioni, questo può anche permetterti di scrivere regex che corrispondono esattamente a ciò che devi abbinare." in realtà non è del tutto preciso.
Wildcard il

1
@Wildcard, grazie per i commenti; questo potrebbe spiegare perché ho avuto problemi a trovare un esempio. Hehe.
Sarnold,

19

http://swtch.com/~rsc/regexp/regexp1.html

Non sono sicuro che sia la migliore spiegazione su Internet, ma è ragionevolmente ben scritta e adeguatamente dettagliata, e continuo a ritornarci. Potresti voler dare un'occhiata.

Se si desidera un livello superiore (spiegazione meno dettagliata), per espressioni regolari semplici come quella che si sta guardando, un motore di espressioni regolari funziona eseguendo il backtracking. In sostanza, sceglie ("mangia") una sezione della stringa e cerca di far corrispondere l'espressione regolare a quella sezione. Se corrisponde, ottimo. In caso contrario, il motore modifica la sua scelta della sezione della stringa e cerca di far corrispondere la regexp a quella sezione, e così via, fino a quando non viene tentata ogni scelta possibile.

Questo processo viene utilizzato in modo ricorsivo: nel tentativo di abbinare una stringa a una determinata espressione regolare, il motore suddivide l'espressione regolare in pezzi e applica l'algoritmo a ciascun pezzo singolarmente.

La differenza tra quantificatori avidi, riluttanti e possessivi si presenta quando il motore sta facendo le sue scelte su quale parte della stringa cercare di abbinare e su come modificare quella scelta se non funziona la prima volta. Le regole sono le seguenti:

  • Un avido quantificatore dice al motore di iniziare con l' intera stringa (o almeno, tutto ciò che non è già stato abbinato da parti precedenti dell'espressione regolare) e controllare se corrisponde al regexp. Se è così, fantastico; il motore può continuare con il resto della regexp. In caso contrario, riprova, ma tagliando un carattere (l'ultimo) dalla sezione della stringa da controllare. Se ciò non funziona, elimina un altro personaggio, ecc. Quindi un avido quantificatore controlla le possibili corrispondenze in ordine dal più lungo al più breve.

  • Un quantificatore riluttante dice al motore di iniziare con il pezzo più corto possibile della stringa. Se corrisponde, il motore può continuare; in caso contrario, aggiunge un carattere alla sezione della stringa da controllare e la prova, e così via fino a quando non trova una corrispondenza o l'intera stringa è stata esaurita. Quindi un quantificatore riluttante controlla possibili corrispondenze nell'ordine dal più breve al più lungo.

  • Un quantificatore possessivo è come un avido quantificatore al primo tentativo: dice al motore di iniziare controllando l'intera stringa. La differenza è che se non funziona, il quantificatore possessivo riferisce che la partita fallì proprio allora. Il motore non modifica la sezione della stringa esaminata e non effettua ulteriori tentativi.

Questo è il motivo per cui la corrispondenza possessiva del quantificatore fallisce nel tuo esempio: .*+viene verificata sull'intera stringa, che corrisponde, ma poi il motore continua a cercare caratteri aggiuntivi foodopo quello - ma ovviamente non li trova, perché tu sei già alla fine della stringa. Se fosse un avido quantificatore, farebbe un .*passo indietro e proverebbe a far corrispondere l' unica fino all'ultimo carattere, quindi fino al terzo all'ultimo carattere, quindi fino al quarto all'ultimo carattere, che ha successo perché solo allora è lì a foosinistra dopo che .*"ha mangiato" la parte precedente della stringa.


1
Questa è una fonte eccellente. Adoro i diagrammi delle macchine a stati. :)
Regex Rookie

@Regex Rookie: felice che ti piaccia :) Dopo aver esaminato quel sito, penso che dovrei chiarire che il suo scopo è quello di promuovere un'implementazione alternativa di un motore di espressione regolare. L'algoritmo di backtracking I (parzialmente) e altre risposte descrivono è il modo lento ; è un algoritmo completamente separato dall'idea NFA / DFA descritta nella pagina Web. Il backtracking è semplicemente più facile da capire, motivo per cui in questo modo i regexps sono in genere spiegati ai principianti.
David Z,

@ David Zaslavsky: buona spiegazione. I tuoi commenti tra parentesi in "Un quantificatore avido dice al motore di iniziare con l'intera stringa (o almeno, tutto ciò che non è già stato abbinato da parti precedenti dell'espressione regolare)" sono importanti. Si applicano anche a quantificatori riluttanti e possessivi. Questo rende la tua spiegazione compatibile con ciò che accade quando cambiamo i nostri modelli di esempio da (". * Foo"; ". *? Foo"; e ". * + Foo") a ("foo. *"; "Foo. *? "; e" pippo. * + ").
John Bentley,

In realtà, xfooxxxxxxfoo corrisponde. * Foo in normale (significato informatico) dell'espressione regolare. L'NFA sarebbe uno stato in cui si snoda tra di sé con qualsiasi personaggio e quindi può saltare al foo. Il DFA sarebbe una traduzione diretta di tale NFA. Può essere fatto in 8 stati.
user4951

@JimThio sì, perché non è un quantificatore possessivo.
David Z,

13

Ecco la mia interpretazione utilizzando le posizioni di cella e indice (vedere il diagramma qui per distinguere una cella da un indice).

Greedy: abbina il più possibile il goloso quantificatore e l'intera regex. Se non c'è corrispondenza, torna indietro sul goloso quantificatore.

Stringa di input: xfooxxxxxxfoo
Regex:. * Foo

Il precedente Regex ha due parti:
(i) '. *' E
(ii) 'pippo'

Ciascuno dei passaggi seguenti analizzerà le due parti. Ulteriori commenti per una corrispondenza a 'Passa' o 'Fallisci' sono spiegati tra parentesi graffe.

Passaggio 1:
(i). * = Xfooxxxxxxfoo - PASS ('. *' È un quantificatore avido e utilizzerà l'intera stringa di input)
(ii) foo = Nessun carattere rimasto da abbinare dopo l'indice 13 - FAIL
Match fallito.

Step 2:
(i). * = Xfooxxxxxxfo - PASS (Backtracking sul quantificatore avido '. *')
(Ii) foo = o - FAIL
Match fallito.

Passaggio 3:
(i). * = Xfooxxxxxxf - PASS (Backtracking sul quantificatore avido '. *')
(Ii) foo = oo - FAIL
Match fallito.

Passaggio 4:
(i). * = Xfooxxxxxx - PASS (backtracking sul quantificatore avido '. *')
(Ii) foo = foo - PASS PASS
MATCH

Risultato: 1 risultato (i)
Ho trovato il testo "xfooxxxxxxfoo" a partire dall'indice 0 e terminando all'indice 13.

Riluttante: abbina il meno possibile al quantificatore riluttante e abbina l'intera regex. se non c'è corrispondenza, aggiungi caratteri al quantificatore riluttante.

Stringa di input: xfooxxxxxxfoo
Regex:. *? Foo

Il regex sopra ha due parti:
(i) '. *?' e
(ii) 'pippo'

Passaggio 1:.
*? = '' (vuoto) - PASS (Abbina il meno possibile al quantificatore riluttante '. *?'. L'indice 0 con '' è una corrispondenza.)
foo = xfo - FAIL (Cella 0,1,2 - ovvero indice tra 0 e 3)
Match fallito.

Passaggio 2:.
*? = x - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. La cella 0 con 'x' è una corrispondenza.)
foo = foo - PASS
Segnala MATCH

Passaggio 3:.
*? = '' (vuoto) - PASS (Abbina il meno possibile al quantificatore riluttante '. *?'. L'indice 4 con '' è una corrispondenza.)
foo = xxx - FAIL (Cella 4,5,6 - ovvero indice tra 4 e 7)
Match fallito.

Passaggio 4:.
*? = x - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella 4.)
foo = xxx - FAIL (Cella 5,6,7 - ovvero indice tra 5 e 8)
Corrispondenza non riuscita.

Passaggio 5:.
*? = xx - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella da 4 a 5.)
foo = xxx - FAIL (Cella 6,7,8 - ovvero indice tra 6 e 9)
Incontro fallito.

Passaggio 6:.
*? = xxx - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella da 4 a 6.)
foo = xxx - FAIL (Cella 7,8,9 - cioè indice tra 7 e 10)
Corrispondenza non riuscita.

Passaggio 7:.
*? = xxxx - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella da 4 a 7.)
foo = xxf - FAIL (Cella 8,9,10 - ovvero indice compreso tra 8 e 11)
Corrispondenza non riuscita.

Passaggio 8:.
*? = xxxxx - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella da 4 a 8.)
foo = xfo - FAIL (Cella 9,10,11 - ovvero indice compreso tra 9 e 12)
Corrispondenza non riuscita.

Passaggio 9:.
*? = xxxxxx - PASS (Aggiungi caratteri al quantificatore riluttante '. *?'. Cella da 4 a 9.)
foo = foo - PASS (Cella 10,11,12 - ovvero indice compreso tra 10 e 13)
Segnala MATCH

Passaggio 10:.
*? = '' (vuoto) - PASS (Abbina il meno possibile al quantificatore riluttante '. *?'. L'indice 13 è vuoto.)
foo = Nessun carattere rimasto da abbinare - FAIL (Non c'è nulla dopo l'indice 13 da abbinare)
Corrispondenza fallito.

Risultato: 2 risultato (i)
Ho trovato il testo "xfoo" che inizia con l'indice 0 e termina con l'indice 4.
Ho trovato il testo "xxxxxxfoo" che inizia con l'indice 4 e termina con l'indice 13.

Possessivo: abbina il più possibile il quantificatore possessivo e abbina l'intera regex. NON tornare indietro.

Stringa di input: xfooxxxxxxfoo
Regex:. * + Foo

Il regex sopra ha due parti: '. * +' E 'pippo'.

Step 1:.
* + = Xfooxxxxxxfoo - PASS (Abbina il più possibile al quantificatore possessivo '. *')
Foo = Nessun carattere rimasto da abbinare - FAIL (Nulla da abbinare dopo l'indice 13)
Incontro fallito.

Nota: il backtracking non è consentito.

Risultato: 0 match (es)


1

Greedy: "abbina la sequenza di caratteri più lunga possibile"

Riluttante: "abbina la sequenza di caratteri più breve possibile"

Possessivo: questo è un po 'strano in quanto NON (in contrasto con avido e riluttante) cerca di trovare una corrispondenza per l'intera regex.

A proposito: nessuna implementazione del matcher pattern regex utilizzerà mai il backtracking. Tutti i pattern matcher nella vita reale sono estremamente veloci, quasi indipendenti dalla complessità dell'espressione regolare!


Per quanto ne so, la maggior parte delle implementazioni di uso generale ora sono così piene di funzionalità che è diventato impossibile non utilizzare il backtracking. Quindi in teoria dovrebbero essere estremamente (esponenzialmente) lenti in alcuni casi. Ma per la maggior parte di questi casi ci sono ottimizzazioni speciali integrate nel pattern matcher.
Robert,

0

La quantificazione Greedy implica la corrispondenza dei pattern utilizzando tutti i caratteri non convalidati rimanenti di una stringa durante un'iterazione. I caratteri non convalidati iniziano nella sequenza attiva . Ogni volta che non si verifica una corrispondenza, il personaggio alla fine viene messo in quarantena e il controllo viene eseguito nuovamente.

Quando solo le condizioni iniziali del modello regex sono soddisfatte dalla sequenza attiva, viene effettuato un tentativo di convalidare le condizioni rimanenti rispetto alla quarantena. Se questa convalida ha esito positivo, i caratteri corrispondenti nella quarantena vengono convalidati e i caratteri residui non corrispondenti rimangono non convalidati e verranno utilizzati quando il processo inizia di nuovo nella successiva iterazione.

Il flusso di caratteri viene dalla sequenza attiva alla quarantena. Il comportamento risultante è che la maggior parte della sequenza originale è inclusa in una corrispondenza possibile.

La quantificazione riluttante è per lo più la qualifica avida, tranne per il fatto che il flusso di caratteri è l'opposto - cioè, iniziano in quarantena e scorrono nella sequenza attiva . Il comportamento risultante è che il meno possibile della sequenza originale è inclusa in una corrispondenza.

La quantificazione possessiva non ha una quarantena e include tutto in una sequenza attiva fissa .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.