Expresiile regulate (RegEx / Regular Expressions) reprezintă un formalism matematic și un mini-limbaj declarativ universal folosit în toate limbajele de programare (JavaScript, Python, PHP, C#, Go, Java, Rust) și uneltele de sistem (grep, sed, awk, VS Code) pentru căutarea, validarea, extragerea și înlocuirea șabloanelor complexe de text. Stăpânirea expresiilor regulate este o abilitate fundamentală pentru orice dezvoltator de software și inginer DevOps.
Această secțiune oferă o documentație completă și aprofundată în limba română pentru sintaxa standard **PCRE / ECMAScript**: de la metacaractere de bază, clase de caractere și cuantificatori, până la noțiuni avansate (aserțiuni *lookaround* cu lățime zero, grupuri atomice, cuantificatori posesivi împotriva atacurilor ReDoS, recursivitate și proprietăți Unicode \p{L}), alături de rețete testate de producție.
// În informatică, există două mari categorii de motoare de expresii regulate:
// 1. Motoare DFA (Deterministic Finite Automaton) - ex: RE2 (Google), Rust regex:
// - Citesc textul caracter cu caracter o singură dată.
// - Garantează timp liniar de execuție O(n) raportat la lungimea textului.
// - IMUNE la atacuri ReDoS (Catastrophic Backtracking)!
// - Dezavantaj: NU suportă aserțiuni complexe (lookaround) sau referințe inverse (backreferences).
// 2. Motoare NFA (Non-Deterministic Finite Automaton / Backtracking) - ex: PCRE, Python re, JS RegExp:
// - Explorează șabloanele ghidate de expresie (Regex-directed).
// - Când o ramură eșuează, motorul face "Backtracking" (se întoarce la ultima bifurcație și încearcă altă variantă).
// - Suportă funcționalități extrem de puternice: grupuri denumite, lookahead/lookbehind, grupuri atomice.
// - Pericol: Expresiile prost construite pot suferi de Catastrophic Backtracking (timp de execuție O(2^n))!
Catastrophic Backtracking și Vulnerabilitățile ReDoS
Un atac de tip Regular Expression Denial of Service (ReDoS) exploatează comportamentul de backtracking al motoarelor NFA. Dacă o expresie regulată conține cuantificatori imbricați sau alternări cu suprapunere (de exemplu: (a+)+$ sau (a|a)+$) și este testată pe un șir de intrare care seamănă cu șablonul dar eșuează la ultimul caracter (cum ar fi "aaaaaaaaaaaaaaaaaaaa!"), numărul de permutări verificate de motor explodează exponențial:
- Pentru 10 caractere: ~1.024 de pași de backtracking.
- Pentru 25 de caractere: ~33.554.432 de pași (procesorul este blocat la 100% timp de câteva secunde).
- Pentru 40 de caractere: peste 1 trilion de pași (serverul îngheață complet până la crash!).
Soluția de producție: Evitați suprapunerea cuantificatorilor, folosiți cuantificatori posesivi (++, *+) sau grupuri atomice (?>...) care împiedică motorul să revină înapoi asupra caracterelor deja consumate.
Matricea Flag-urilor Globale (Modificatorii de Comportament)
Flag-urile modifică modul în care motorul interpretează întregul șablon text:
| Flag | Nume Mod | Comportament & Efect Practic |
|---|---|---|
g |
Global | Găsește toate potrivirile din text, nu doar prima apariție (esențial în JavaScript pentru matchAll și replaceAll). |
i |
Case-Insensitive | Ignoră diferența dintre majuscule și minuscule (a-z se potrivește și cu A-Z). |
m |
Multiline | Schimbă comportamentul ancorelor: ^ și $ se potrivesc la începutul și sfârșitul fiecărei linii individuale (după \n), nu doar al întregului text. |
s |
DotAll / Single-line | Forțează metacaracterul punct (.) să se potrivească inclusiv cu caracterele de linie nouă (\n). |
u |
Unicode | Activează suportul complet pentru puncte de cod Unicode pe 21 de biți (UTF-8/UTF-16) și permite clasele \p{L}. |
x |
Extended / Verbose | Ignoră spațiile albe nespecificate și permite adăugarea de comentarii cu # direct în interiorul expresiei. |
Matricea Aserțiunilor Lookaround (Zero-Width Assertions)
Aserțiunile Lookaround verifică dacă un anumit context există înainte sau după poziția curentă, fără a consuma niciun caracter din text (lățime zero). Acest lucru permite aplicarea de condiții multiple simultan sau extragerea valorilor fără delimitatorii adiacenți:
| Sintaxă | Tip Aserțiune | Condiție Verificată | Exemplu Practic |
|---|---|---|---|
(?=...) |
Positive Lookahead | Textul următor trebuie să se potrivească cu șablonul din interior. | \d+(?= RON) → găsește cifrele doar dacă sunt urmate imediat de ” RON”, dar extrage DOAR cifrele! |
(?!...) |
Negative Lookahead | Textul următor nu are voie să se potrivească cu șablonul. | \b(?!admin\b)\w+ → găsește orice cuvânt cu excepția cuvântului „admin”. |
(?<=...) |
Positive Lookbehind | Textul precedent trebuie să se potrivească cu șablonul. | (?<=\$)\d+ → găsește cifrele precedate de simbolul dolar, dar extrage DOAR cifrele! |
(?<!...) |
Negative Lookbehind | Textul precedent nu are voie să se potrivească cu șablonul. | (?<!\\)" → găsește ghilimelele care NU sunt escapate cu backslash. |