Cuantificatori Leneși vs. Lacomi (Lazy vs. Greedy) în Expresii Regulare (RegEx)

Cuantificatori și Backtracking Standard RegEx Universal

Controlul comportamentului de potrivire pentru a preveni înghițirea întregului text și a evita colapsul serverului prin backtracking catastrofic.

Tipar RegEx
.* (Greedy) vs. .*? (Lazy)

În mod implicit, toți cuantificatorii standard din expresiile regulare (`*`, `+`, `{n,}`) sunt Lacomi (Greedy): încearcă să consume cât mai multe caractere posibil din text, oprindu-se abia la ultimul caracter care satisface condiția.

Acest comportament produce erori frecvente la parsarea de HTML sau JSON: expresia `

.*

` aplicată pe textul `

Unu

Doi

` nu va potrivi primul paragraf, ci va înghiți tot textul de la primul `

` până la ultimul `

` de pe pagină!

Adăugarea semnului întrebării transformă cuantificatorul într-unul Leneș (Lazy / Reluctant): .*? consumă numărul minim necesar de caractere, oprindu-se imediat la prima apariție a delimitatorului final. De asemenea, înțelegerea acestei diferențe este esențială pentru a preveni atacurile de tip ReDoS (Regular Expression Denial of Service).

Sintaxă, opțiuni și concepte cheie

Opțiune / Concept Descriere practică
.* (Greedy) Consumă cel mai lung șir posibil de caractere până la finalul textului.
.*? (Lazy) Consumă cel mai scurt șir posibil de caractere oprindu-se la prima potrivire validă.
+? (Lazy Plus) Potrivește cel puțin un caracter, dar cât mai puține posibil.
Catastrophic Backtracking Fenomenul în care cuantificatorii imbricați lacomi blochează procesorul la 100%.

Exemple practice și cod

Exemplul 1: Extragerea corectă a tag-urilor HTML dintr-un document

Diferența dintre potrivirea lacomă și cea leneșă.

Text de test:
"Titlu Unu și Titlu Doi"

1. Cuantificator Greed (Greșit):
Expresie: .*
Rezultat: "Titlu Unu și Titlu Doi" (o singură potrivire uriașă nedorită!)

2. Cuantificator Lazy (Corect):
Expresie: .*?
Rezultat 1: "Titlu Unu"
Rezultat 2: "Titlu Doi" (două potriviri distincte curate!)

Rezultat & Impact

Separare perfectă a elementelor fără a înghiți textul intermediar.

Greșeli frecvente și bune practici

  • Folosirea `.*?` pentru parsarea structurilor imbricate adânc de HTML/XML; regex-ul nu poate ține evidența parantezelor imbricate corect (folosiți un parser DOM dedicat).
  • Scrierea de expresii de tipul `(a+)+$` care generează complexitate de calcul exponențială $O(2^n)$ la șiruri lungi de caractere neconforme.

Ghiduri și noțiuni înrudite