Ghid pentru Tester regex
Cum testați expresii regulate JavaScript cu Testerul regex XGM: flaguri, grupuri, sintaxa de înlocuire și cum evitați tiparele lente și greșelile obișnuite.
Bazele expresiilor regulate
O expresie regulată descrie o mulțime de șiruri printr-o sintaxă compactă: caractere literale, clase de caractere, cuantificatori și grupuri. Motorul parcurge textul de intrare și raportează unde se potrivește tiparul. Testerul XGM folosește motorul JavaScript al browserului, așa că rezultatele corespund cu ce fac String.prototype.match, matchAll și replace în codul dumneavoastră. Nu există nicio diferență între a încerca același tipar în consola browserului și a-l încerca aici, doar că instrumentul arată potrivirile și grupurile într-o formă lizibilă. A vedea potrivirile este mai rapid și mai sigur decât a încerca să vă imaginați ce face tiparul.
| Sintaxă | Semnificație | Exemplu |
|---|---|---|
. | Orice caracter, mai puțin sfârșitul de linie (dacă lipsește s) | a.c potrivește abc |
\d, \w, \s | Cifră, caracter de cuvânt, spațiu alb | \d{4} potrivește 2026 |
[abc], [^abc] | Unul dintre caractere sau niciunul dintre ele | [aeiou] |
*, +, ? | 0 sau mai multe, 1 sau mai multe, 0 sau 1 | colou?r |
{n,m} | Între n și m repetări | \d{2,4} |
^, $ | Începutul și sfârșitul textului (sau al liniei, cu m) | ^Error |
\b | Limită de cuvânt | \bcat\b |
( ), (?<name> ) | Grup de captură, grup denumit | (?<year>\d{4}) |
(?: ) | Grup fără captură | (?:https?|ftp):// |
a|b | Alternanță | jpg|png |
(?= ), (?! ) | Lookahead, lookahead negativ | \d+(?=px) |
Cum folosiți Testerul regex
- Deschideți Testerul regex și introduceți tiparul fără barele oblice din jur, de exemplu
(?<year>\d{4})-(?<month>\d{2}). - Setați flaguri precum
g,isaum. - Lipiți textul de test. Potrivirile sunt evidențiate și listate împreună cu grupurile lor.
- Activați Înlocuire și introduceți un text de înlocuire ca să vedeți rezultatul, folosind
$1,$<name>sau$&.
Un exemplu practic: ca să găsiți nume de gazdă din example.com într-un jurnal, tiparul \b[a-z0-9-]+\.example\.com\b cu flagurile gi potrivește www.example.com și API.example.com, dar nu example.com.evil.example.net, datorită limitei de cuvânt de după com. Încercați variante în tester ca să vedeți ce linii se potrivesc și de ce. Scoaterea limitei de cuvânt și compararea rezultatelor este cel mai rapid mod de a explica la ce folosește ea.
Păstrați un set de linii de test alături de tipar, de pildă într-un comentariu lângă cod. Când cineva schimbă tiparul mai târziu, lipirea acelor linii în tester arată imediat dacă s-a modificat comportamentul. Acest obicei mic scoate întreținerea expresiilor regulate din zona presupunerilor. Chiar dacă liniile sunt puține, o notă scurtă despre rolul fiecăreia economisește timp serios mai târziu.
Testați cu text realist, inclusiv cu situațiile care nu ar trebui să se potrivească. Un tipar care găsește orice dată validă este abia pe jumătate gata până când verificați că respinge și 2026-13-45 sau un număr de telefon care arată asemănător. Fals-pozitivele costă adesea mai mult decât potrivirile lipsă, pentru că produc date greșite fără să se plângă nimeni. Adăugați în aceeași listă și exemplele care trebuie să se potrivească, dar arată neobișnuit.
Flaguri
| Flag | Nume | Efect |
|---|---|---|
g | Global | Găsește toate potrivirile, nu doar prima |
i | Ignore case | Potrivire fără deosebire între majuscule și minuscule |
m | Multiline | ^ și $ se potrivesc la începutul și la sfârșitul fiecărei linii |
s | dotAll | . potrivește și sfârșitul de linie |
u | Unicode | Puncte de cod Unicode și secvențe de proprietate \p{…} |
v | Unicode sets | Ca u, plus operații cu mulțimi în clase; nu se combină cu u |
y | Sticky | Potrivește doar la poziția curentă (lastIndex) |
d | Indices | Raportează indicii de început și de sfârșit ai grupurilor |
Flagul u contează pentru orice depășește ASCII. Fără el, un emoji este numărat ca două unități de cod separate, iar \p{L}, adică "orice literă", nu este disponibil. Cu u, \p{L}+ potrivește cuvinte din orice sistem de scriere, precum Ștefan sau Zürich. În textele românești diferența se vede imediat: literele cu diacritice nu intră în \w, dar intră în \p{L}. Fiindcă adăugarea ulterioară a unui flag poate schimba sensul tiparului, testați de la bun început cu flagurile corecte.
Sintaxa de înlocuire
| Tipar | Inserează |
|---|---|
$& | Întreaga potrivire |
$1, $2, … | Grup numerotat |
$<name> | Grup denumit |
$$ | Un semn dolar literal |
$' | Textul de după potrivire (un semn dolar urmat de un accent grav inserează textul dinaintea ei) |
Pattern: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Flags: g
Replacement: $<day>.$<month>.$<year>
Input: Released 2026-09-15, patched 2026-10-01
Output: Released 15.09.2026, patched 01.10.2026Tipare lente și backtracking catastrofal
Motorul regex din JavaScript se bazează pe backtracking: când o parte a tiparului eșuează, motorul se întoarce și încearcă alte moduri de potrivire. Cuantificatorii imbricați peste caractere care se suprapun, precum (a+)+$ sau (\w|\d)*x, pot face ca numărul de încercări să crească exponențial cu lungimea textului. Câteva zeci de caractere pot dura atunci secunde sau chiar mai mult. Partea perfidă este că, pe date de test scurte, totul pare rapid.
Aceasta este o problemă reală de securitate, numită ReDoS (refuz de serviciu prin expresii regulate): un server care rulează un astfel de tipar pe datele trimise de utilizatori poate fi blocat de o singură cerere construită anume. Testerul rulează tiparele într-un web worker și le oprește după 1,5 secunde, așa că vedeți "Oprit după 1,5 secunde" în loc de o filă înghețată. Dacă un tipar atinge această limită, același tipar este un risc și pe serverul dumneavoastră. În loc să îl lăsați așa, rescrieți-l cu o clasă de caractere mai strâmtă.
| Riscant | Mai sigur | De ce |
|---|---|---|
(a+)+ | a+ | Cuantificatori imbricați peste aceleași caractere |
(\w|\d)* | \w* | \d face deja parte din \w, așa că alternativele se suprapun |
.*.*= | [^=]*= | Doi metacaracteri lacomi concurează pentru același text |
^(\s*\w+\s*)+$ | ^\s*\w+(?:\s+\w+)*\s*$ | Faceți separatorii obligatorii între repetări |
Limitați datele de intrare pe servere
Greșeli frecvente
- Uitarea escapării.
.potrivește orice caracter; folosiți\.pentru un punct literal, de exemplu înexample\.com. - Validare neancorată.
\d{5}se potrivește și în interiorul lui123456; folosiți^\d{5}$ca să validați o valoare întreagă. - Metacaractere lacome.
<.*>potrivește de la primul<până la ultimul>de pe linie; folosiți<[^>]*>sau varianta leneșă<.*?>. - Escapare dublă în cod. Un tipar scris ca șir în JavaScript are nevoie de bare oblice inverse duble (
"\\d"); testerul așteaptă forma din literalul regex (\d). - Folosirea lui `g` cu `test()` într-o buclă. Flagul global păstrează
lastIndexîntre apeluri, așa că apeluriletestrepetate pe aceeași expresie alternează între adevărat și fals.
Pentru URL-uri, URL și UTM desface o adresă în părțile ei mult mai sigur decât un tipar. Pentru formate de date, Instrumente JSON validează structura cu adevărat. Regula generală este simplă: dacă un format are o gramatică oficială, citiți-l cu un parser și păstrați expresia regulată doar pentru căutarea în text. Explicați fiecare tipar printr-un comentariu de o linie înainte să ajungă în producție; peste șase luni, acel comentariu se citește mult mai repede decât se descifrează tiparul.
Întrebări frecvente
Ce dialect de regex folosește testerul?
JavaScript, așa cum este implementat de browserul dumneavoastră. Rezultatele corespund cu ce face același tipar în cod JavaScript, în acel browser.
De ce nu funcționează tiparul meu din Python sau PCRE?
Dialectele diferă. JavaScript nu are cuantificatori posesivi, nu are grupuri atomice și nu acceptă, în majoritatea browserelor, modificatori inline precum (?i), iar unele secvențe de escapare se comportă altfel.
De ce a fost oprit testul meu după 1,5 secunde?
Tiparul a făcut prea mult backtracking pe textul de intrare, semn de backtracking catastrofal. Simplificați cuantificatorii imbricați sau pe cei care se suprapun.
Cum potrivesc text pe mai multe linii?
Folosiți flagul s, ca . să potrivească sfârșitul de linie, sau [\s\S]. Folosiți m dacă vreți ca ^ și $ să se potrivească la fiecare linie.
Care este diferența dintre $1 și $<name>?
$1 se referă la un grup după poziție; $<name> se referă la un grup denumit și continuă să funcționeze când adăugați grupuri noi în tipar.
Textul meu de test este încărcat undeva?
Nu. Tiparul și textul sunt procesate în browserul dumneavoastră, într-un fir de tip worker al paginii.
Poate regex să valideze adrese de e-mail?
Doar aproximativ. Sintaxa completă a adreselor este complicată; abordarea practică este un tipar simplu, însoțit de un e-mail de confirmare.
Ce face flagul d?
Adaugă la rezultatele potrivirii indicii de început și de sfârșit pentru fiecare grup de captură, ceea ce este util pentru evidențiere sau pentru editoare.
Ar trebui să folosesc regex ca să analizez HTML?
Nu, dincolo de fragmente simple și cunoscute. Imbricarea din HTML și sintaxa opțională fac tiparele fragile; folosiți parserul DOM al browserului sau o bibliotecă serioasă de analiză HTML.
De ce nu potrivește \w literele cu diacritice?
\w înseamnă litere ASCII, cifre și liniuță de subliniere. Folosiți \p{L} cu flagul u pentru litere din orice sistem de scriere.