Regular Expressions Avidità contro pigrizia


Esempio

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.