Ricerca…


Parametri

quantificatori Descrizione
? Abbina il carattere precedente o la sottoespressione 0 o 1 volte (preferibilmente 1).
* Abbina il carattere precedente o la sottoespressione 0 o più volte (il più possibile).
+ Abbina il precedente carattere o sottoespressione 1 o più volte (il maggior numero possibile).
{n} Abbina il carattere o la sottoespressione precedente esattamente n volte.
{min,} Far corrispondere il carattere precedente o sottoespressione min o più volte (il maggior numero possibile).
{0,max} Abbina il carattere o la sottoespressione precedente al massimo o al massimo (il più vicino possibile al massimo ).
{min,max} Abbina il carattere o la sottoespressione precedente almeno min volte ma non più di max volte (il più vicino possibile al massimo ).
Quantificatori pigri Descrizione
?? Abbina il carattere precedente o la sottoespressione 0 o 1 volte (preferibilmente 0).
*? Abbina il carattere precedente o la sottoespressione 0 o più volte (il meno possibile).
+? Abbina il carattere precedente o la sottoespressione 1 o più volte (il meno possibile).
{n}? Abbina il carattere o la sottoespressione precedente esattamente n volte. Nessuna differenza tra la versione avida e pigra.
{min,}? Corrisponde al carattere o espressione che precede min o più volte (il più vicino a min possibile).
{0,max}? Abbina il carattere o la sottoespressione precedente al massimo o al massimo (il meno possibile).
{min,max}? Abbina il carattere o la sottoespressione precedente almeno min volte ma non più di max volte (il più vicino possibile al minimo ).

Osservazioni

golosità

Un quantificatore avido tenta sempre di ripetere il sub-pattern il più volte possibile prima di esplorare le corrispondenze più brevi con il backtracking.

Generalmente, un modello goloso corrisponderà alla stringa più lunga possibile.

Per impostazione predefinita, tutti i quantificatori sono golosi.

Pigrizia

Un pigro (chiamato anche non avido o riluttante) quantificatore tenta sempre di ripetere il sub-pattern come meno possibile, prima di esplorare corrisponde più dall'espansione.

Generalmente, un modello pigro corrisponderà alla stringa più breve possibile.

Per rendere i quantificatori pigri, basta aggiungere ? al quantificatore esistente, ad esempio +? , {0,5}? .

Il concetto di avidità e pigrizia esiste solo nei motori di backtracking

La nozione di quantificatore avido / pigro esiste solo nei motori regex di backtracking. Nei motori regex non di retromarcia o nei motori regex conformi a POSIX, i quantificatori specificano solo il limite superiore e il limite inferiore della ripetizione, senza specificare come trovare la corrispondenza - quei motori corrisponderanno sempre alla stringa più lunga a sinistra, indipendentemente.

Avidità contro pigrizia

Dato il seguente input:

aaaaaAlazyZgreeedyAlaaazyZaaaaa

Useremo due schemi: uno avido: A.*Z e uno pigro: A.*?Z Questi modelli producono le seguenti corrispondenze:

Innanzitutto concentrati su ciò che fa A.*Z Quando ha abbinato il primo A , il .* , Essendo avidi, cerca di abbinarne altrettanti . il più possibile

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \________________________/
      A.* matched, Z can't match

Poiché la Z non corrisponde, i backtrack del motore e .* devono quindi corrispondere ad un numero inferiore . :

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \_______________________/
      A.* matched, Z can't match

Succede qualche altra volta, finché non arriva a questo:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \__________________/
      A.* matched, Z can now match

Ora Z può corrispondere, quindi il modello generale corrisponde:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \___________________/
      A.*Z matched

Al contrario, la riluttante (pigra) ripetizione in A.*?Z corrisponde per prima a pochi . come possibile, e poi prendendo di più . come necessario. Questo spiega perché trova due corrispondenze nell'input.

Ecco una rappresentazione visiva di ciò che i due modelli corrispondono:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \____/l      \______/l      l = lazy
     \_________g_________/       g = greedy

Esempio basato sulla risposta fatta da poligenelubrificanti .

Lo standard POSIX non include il ? operatore, così tanti motori regex POSIX non hanno una corrispondenza lenta. Sebbene il refactoring, in particolare con il "trucco più grande di sempre" , possa in alcuni casi essere d'aiuto, l'unico modo per avere una vera corrispondenza lazy è usare un motore che lo supporta.

Confini con più corrispondenze

Quando hai un input con limiti ben definiti e ti aspetti più di una corrispondenza nella stringa, hai due opzioni:

  • Usando quantificatori pigri;
  • Utilizzando una classe di caratteri negata.

Considera quanto segue:

Hai un semplice motore di template, vuoi sostituire sottostringhe come $[foo] dove foo può essere qualsiasi stringa. Vuoi sostituire questa sottostringa con qualsiasi cosa basata sulla parte tra [] .

Puoi provare qualcosa come \$\[(.*)\] , E quindi usare il primo gruppo di cattura.

Il problema è che se hai una stringa come something $[foo] lalala $[bar] something else tua partita sarà

something $[foo] lalala $[bar] something else
          | \______CG1______/|
          \_______Match______/

Il gruppo di cattura è foo] lalala $[bar che può o non può essere valida.

Hai due soluzioni

  1. Usando la pigrizia: in questo caso fare * pigro è un modo per andare a trovare le cose giuste. Quindi cambi la tua espressione in \$\[(.*?)\]

  2. Usando la classe di caratteri negata: [^\]] cambi la tua espressione in \$\[([^\]]*)\] .

In entrambe le soluzioni, il risultato sarà lo stesso:

something $[foo] lalala $[bar] something else
          | \_/|        | \_/|
          \____/        \____/

Con il gruppo di cattura che è rispettivamente foo e bar .


L'uso della classe di caratteri negata riduce il problema del backtracking e può far risparmiare molto tempo alla CPU quando si tratta di input di grandi dimensioni.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow