Ho una confessione che farà sussultare i puristi del regex: per i primi anni della mia carriera, ho scritto espressioni regolari facendo copy-pasting da Stack Overflow, cambiando un carattere, eseguendo il codice, vedendolo fallire e ripetendo fino a quando non è successo ho fatto' t capire gli schemi - li ho costretti alla sottomissione Era lento e, peggio ancora, gli schemi che ho spedito erano fragili in modi che potevo' t vedere.
Ciò che ha risolto era & #39; t leggere la teoria (anche se alla fine l'ho fatto) Era un tester visivo - una scatola in cui digito il modello, una scatola in cui incollo le stringhe di prova e le corrispondenze che si illuminano nell'istante in cui cambio qualcosa All'improvviso ho potuto visitare perché \d+ Afferrato più di quanto volevo, o perché il mio schema di posta elettronica rifiutava un indirizzo perfettamente valido. Regex ha smesso di essere un gioco di indovinare ed è diventato un ciclo di feedback stretto.
Questo è esattamente ciò che il Costruttore di regex su Toolz.dev è. scrivi un modello, fai cadere i dati di test, attiva/disattiva le bandiere e guarda le partite e i gruppi catturati evidenziare in tempo reale Funziona interamente nel tuo browser, quindi le righe di registro o i dati utente you' sono in fase di test contro non essere mai caricato da nessuna parte Questa guida è il riferimento regex che vorrei I' avevo allora - i modelli che riutilizzo effettivamente, un cheat sheet completo e l'unico errore che può abbattere un server di produzione.
tl; dr: Incolla il tuo modello e le stringhe di prova nel Costruttore di regex e alternare il
g/i/mFlag per vedere le partite evidenziare dal vivo. Inizia in modo semplice, aggiungi vincoli per uccidere i falsi positivi e testa gli input contraddittori per evitare un backtracking catastrofico. Per i dati estratti, accoppialo con il Formattatore JSON e convertitore base64. Tutto lato client, tutto gratuito.
Che cos'è esattamente un'espressione regolare?
Un'espressione regolare - regex o regexp - è una stringa compatta che descrive un modello di ricerca Invece di & quot;trova la parola cat, & quot; puoi dire & quot;trova qualsiasi numero di cinque cifre, & quot; & quot;trova qualsiasi cosa che assomigli a un'email, & quot; o & quot;trova ogni riga che inizia con ERROR.& quot; Quasi ogni linguaggio e editor li supporta, che è ciò che rende l'abilità così portatile: imparala una volta e la usi in JavaScript, Python, il tuo grep, e il tuo trovare e sostituire il tuo IDE.
Il concetto deriva dalla teoria del linguaggio formale degli anni '50 e Ken Thompson lo cablava nel calcolo negli anni '60 per l'editing di testo. Quella storia conta per una ragione pratica che tornerò a: "regolari" hanno dei limiti, motivo per cui la regex non può davvero analizzare le strutture nidificate come l'HTML, non importa quanto tu possa essere intelligente.
Dove raggiungo la regex in una settimana normale: convalidare l'input dell'utente prima che colpisca il database, estrarre i campi da linee di registro non strutturate, eseguire la ricerca e la sostituzione su un intero codebase che una ricerca semplice non può esprimere e filtrare i dati durante una migrazione. la Costruttore di regex è dove prototipo tutti di quelli prima che si avvicinino al codice reale.
Ecco gli elementi costitutivi fondamentali - l'alfabeto da cui assembli i modelli
| sintassi | significato | esempio | fiammiferi |
|---|---|---|---|
. |
Qualsiasi personaggio tranne Newline | h.t |
cappello, caldo, colpire |
\d |
Qualsiasi cifra (0-9) | \d{3} |
123, 456 |
\w |
Parola Char (A-Z, A-Z, 0-9, _) | \w+ |
Ciao, test_123 |
\s |
Qualsiasi spazio bianco | hello\sworld |
Ciao mondo |
^ |
Inizio stringa | ^Hello |
Ciao all'inizio |
$ |
Fine della stringa | end$ |
Fine alla fine |
* |
Zero o più | ab*c |
AC, ABC, ABC |
+ |
uno o più | ab+c |
ABC, ABC |
? |
Zero o uno | colou?r |
colore, colore |
{n} |
Esattamente N volte | \d{4} |
2026 |
{n,m} |
tra N e M | \d{2,4} |
12, 123, 1234 |
[abc] |
classe dei personaggi | [aeiou] |
qualsiasi vocale |
[^abc] |
classe negata | [^0-9] |
Qualsiasi non cifra |
(...) |
Cattura gruppo | (hello) |
cattura "ciao" |
a|b |
alternanza (o) | cat|dog |
Gatto o cane |
Quali modelli di regex dovrebbero tenere a portata di mano ogni sviluppatore?
Questi sono quelli che ho testato, rotto, riparato e ora conservo in un file di snippet personale. copiali direttamente nel Costruttore di regex E lancia loro i tuoi casi di bordo.
Email (il tipo pratico)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
Questo corrisponde [email protected] e [email protected], e rifiuta @example.com oppure user@com. Ecco l'importante onestà, però: la grammatica completa dell'e-mail in RFC 5322 è mostruosamente complesso: tecnicamente consente stringhe e commenti citati che quasi nessuno utilizza Don' t inseguire la conformità RFC al 100% con un regex. Abbina il pratico 99% al modello sopra, quindi conferma che l'indirizzo è reale inviando un'e-mail di verifica. That's l'errore che vedo di più: squadre che bruciano giorni su un & quot;airtight" email regex che può ancora't dire una vera casella di posta da un errore di battitura.
URL
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$
fiammiferi https://toolz.dev e http://www.example.com/path?query=value; rifiuta ftp://... e testo in chiaro.
Numero di telefono degli Stati Uniti
^(\+1)?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$
Abbastanza flessibile per 555-123-4567, (555) 123-4567, +1 555.123.4567, e 5551234567.
Indirizzo IPv4
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
L'alternanza nidificata è ciò che impone che ogni ottetto rimanga in 0–255, quindi rifiuta correttamente 999.999.999.999.
Controllo password forte
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
Richiede almeno 8 caratteri con un minuscolo, un maiuscolo, una cifra e un simbolo. la (?=...) i lookahead affermano ciascuno una condizione senza consumare personaggi: un bel trucco che vale la pena comprendere.
Data ISO (AAAA-MM-GG)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
fiammiferi 2026-07-11, rifiuta 2026-13-01 e 2026-02-32.
colore esadecimale
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
fiammiferi #4466EE, #abc, #000000.
il cheat sheet regex
Tieni questo appuntato. È il riferimento che controllo di più.
ancora
| modello | descrizione |
|---|---|
^ |
Inizio della stringa (o linea in modalità multilinea) |
$ |
Fine della stringa (o riga in modalità multilinea) |
\b |
Confine delle parole |
\B |
Confine non di parole |
quantificatori
| modello | descrizione |
|---|---|
* |
0 o più (avido) |
+ |
1 o più (avidi) |
? |
0 o 1 (avido) |
*? +? ?? |
Versioni pigre - abbina il meno possibile |
{n} {n,} {n,m} |
esattamente N / N o più / tra N e M |
Classi di caratteri
| modello | descrizione |
|---|---|
[abc] |
a, b o c |
[^abc] |
non A, B o C |
[a-z] [A-Z] [0-9] |
polivale |
\d \D |
Cifra / Non cifra |
\w \W |
parola char / char non di parole |
\s \S |
Spazi bianchi / Spazi non bianchi |
Gruppi e guardarsi
| modello | descrizione |
|---|---|
(abc) |
Gruppo di cattura |
(?:abc) |
Gruppo che non cattura |
(?<name>abc) |
gruppo di acquisizione nominato |
(?=abc) / (?!abc) |
Lo sguardo positivo/negativo |
(?<=abc) / (?<!abc) |
aspetto positivo/negativo dietro |
bandiera
| imbandiera | descrizione |
|---|---|
g |
Globale - trova tutte le corrispondenze |
i |
insensibile alla maiuscola |
m |
Multiline - ^ e $ Abbina i limiti della linea |
s |
Dotall- . Corrisponde alle nuove righe |
u |
Supporto Unicode |
Come si costruisce ed esegue il debug di uno schema senza perdere un'ora?
Il mio processo è noioso di proposito, perché noioso è ripetibile:
- Inizia con la cosa più semplice che corrisponde a un esempio reale. Non cercare di gestire ogni caso in una volta.
- Incolla sia stringhe di test positive che negative dentro Costruttore di regex- cose che dovrebbero corrispondere e cose che non devono.
- Stringere per uccidere i falsi positivi. Aggiungi ancoraggi (
^,$) in modo che il modello corrisponda all'intera stringa e scambia.Per classi specifiche come[a-z]oppure[^,]. - lancia un input contraddittorio- stringhe vuote, ingressi enormi, Unicode e caratteri regex letterali come dati.
- Solo allora ottimizza.
Quando qualcosa si comporta male, è quasi sempre una delle tre cose. se Corrisponde troppo, i tuoi quantificatori sono avidi - rendili pigri (*?) o le tue classi più specifiche. se Corrisponde troppo poco, probabilmente hai bisogno del i Segnala o dimentica di sfuggire a un carattere speciale. se non corrisponde a niente, controlla i metacaratteri non evasi (., *, +, (, [, {, ecc.) Inteso per essere caratteri letterali o invisibili come le schede nascoste nella stringa di prova.
Che cos'è un backtracking catastrofico e perché dovresti temerlo?
Questa è la sezione che ho tatuaggio sui nuovi sviluppatori, se potessi. All'inizio ho spedito una regex di convalida dell'input che sembrava completamente innocente, e un pomeriggio una singola richiesta ha fissato un core della CPU al 100% e sono rimasto lì. Il modello era il problema.
Quando un motore regex non riesce a trovare una corrispondenza, esso Sck track- si ritira e tenta altri modi per soddisfare il pattern Certe forme fanno esplodere esponenzialmente il numero di percorsi L'esempio da manuale:
^(a+)+$
alimentalo un input come aaaaaaaaaaaaaaaaaaaab (una corsa di a terminando con a b), e i quantificatori nidificati danno al motore un numero astronomico di modi per dividere il as, tutto ciò che prova prima di concludere "Nessuna corrispondenza". La tua app si blocca. Questa è una vera classe di negazione del servizio chiamata Redos (Espressione regolare del servizio) e gli aggressori lo sfruttano.
Come stare al sicuro:
- Mai quantificatori di nidificazione.
(a+)+,(a*)*, e(a+)*sono bandiere rosse. - Usa gruppi atomici o quantificatori possessivi Dove il motore li supporta:
(?>a+)oppurea++. - essere specifico.
[a-z]+Backtracks Meno di.+Perché ha meno percorsi da esplorare. - Ancorare i tuoi modelli Quindi il motore si guasta velocemente sull'ingresso non corrispondente.
- prova con stringhe che quasi corrispondono ma falliscono alla fine- quello' è il caso peggiore per fare marcia indietro.
Se sei in movimento, questo problema semplicemente non esiste, il che mi porta alla sezione successiva.
In che modo la regex differisce tra le lingue?
La sintassi di base viaggia bene, ma i dettagli mordono. Queste sono le differenze che ho effettivamente inciampato.
javascript:
const regex = /\d{3}-\d{4}/g;
const pattern = new RegExp('\\d{3}-\\d{4}', 'g'); // note the doubled backslashes
'555-1234'.match(regex); // ["555-1234"]
const m = '2026-07-11'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
m.groups.year; // "2026"
Attenzione: Lookbehind è arrivato solo in ES2018, \d corrisponde solo alle cifre ASCII e il g Bandiera fa .test() stateful via lastIndex- una sottile fonte di bug nei cicli.
Pitone:
import re
pattern = re.compile(r'\d{3}-\d{4}') # raw strings avoid double-escaping
pattern.findall('Call 555-1234 or 555-5678') # ['555-1234', '555-5678']
Usa sempre stringhe grezze (r'...'). rammentare re.match solo ancoraggi all'inizio - utilizzare re.search da trovare ovunque. e re.VERBOSE Ti consente di scrivere modelli commentati a più righe, che è un vero toccasana per quelli complessi.
PHP: I modelli hanno bisogno di delimitatori ('/\d{3}-\d{4}/'), utilizza il potente motore PCRE e preg_match rientro 1, 0, o false sull'errore - quindi controlla con ===.
ANDARE: utilizza il motore RE2, che deliberatamente Gocce di lookhead, lookbehinds e backreferences in cambio di una garanzia di corrispondenza lineare-tempo Significa che non è nemmeno possibile alcun backtracking catastrofico - un vero e proprio diverso compromesso che vale la pena conoscere quando si sceglie una lingua per la corrispondenza non attendibile-input.
Un esempio reale: analizzare una riga di registro Apache
Ecco il genere di cose in cui regex è davvero eccezionale. Una riga di registro di accesso standard di Apache è simile a:
192.168.1.1 - frank [11/Jul/2026:10:27:10 -0500] "GET /api/users HTTP/1.1" 200 1234
Questo modello lo separa:
^(\S+) \S+ (\S+) \[([^\]]+)\] "(\S+) (\S+) (\S+)" (\d{3}) (\d+)$
incollare entrambi nel Costruttore di regex E ogni gruppo catturato si accende separatamente:
| gruppo | contento | esempio |
|---|---|---|
| 1 | Indirizzo IP | 192.168.1.1 |
| 2 | nome utente | schietto |
| 3 | marca temporale | 11/luglio/2026:10:27:10 -0500 |
| 4 | Metodo HTTP | venire |
| 5 | Percorso della richiesta | /api/utenti |
| 6 | Versione HTTP | http/1.1 |
| 7 | codice di stato | 200 |
| 8 | Dimensione risposta | 1234 |
Una volta che i gruppi si allineano nel tester, traducendolo in a re.findall in Python o a match() in JavaScript è banale - e sai già che funziona.
Domande frequenti
Che cos'è un generatore di regex?
Un generatore di regex è uno strumento interattivo in cui si digita un'espressione regolare e la si vede immediatamente abbinata a stringhe di test, con le corrispondenze e i gruppi acquisiti evidenziati. Sostituisce il ciclo di riscrittura del errore di scrittura lenta nel codice con uno live. la Costruttore di regex Su Toolz.dev lo fa interamente nel tuo browser, quindi i dati di prova rimangono sulla tua macchina.
I modelli di regex sono identici in ogni linguaggio di programmazione?
La sintassi di base è quasi identica, ma i dettagli differiscono abbastanza da causare bug. JavaScript più vecchio non ha un lookbehind, il motore RE2 di Go non ha affatto lookahead o backreferences e gruppi di nomi Python con (?P<name>...) in alcuni contesti. Conferma sempre un modello nella lingua che stai effettivamente prendendo di mira piuttosto che assumere la portabilità.
Come posso convalidare un indirizzo email con regex?
Usa un modello pratico come ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$, che gestisce la stragrande maggioranza degli indirizzi reali Non tentare la piena conformità RFC 5322 in un regex - la grammatica è fin troppo complessa e you'll ancora rifiutare indirizzi validi o accettare errori di battitura Accoppiare il regex con una e-mail di verifica per confermare la casella di posta effettivamente esistente.
Perché la mia regex blocca l'applicazione?
Quasi sempre un catastrofico backtracking. Pattern con quantificatori nidificati come (a+)+ Crea un numero esponenziale di percorsi corrispondenti quando incontrano input che quasi corrisponde ma alla fine falliscono e il motore li prova tutti. rimuovere i quantificatori nidificati, preferire classi di caratteri specifiche a .+, e aggiungi ancoraggi in modo che il motore possa guastarsi rapidamente.
Posso usare la regex per analizzare html o json?
No, non per niente oltre l'estrazione banale HTML e JSON non sono linguaggi regolari - permettono un nesting arbitrario che regex fondamentalmente non può tracciare Usa un parser reale: DOMParser o Cheerio per HTML, e JSON.parse O uno strumento JSON per JSON. Regex è lo strumento sbagliato nel momento in cui la struttura si annida.
Qual è la differenza tra abbinamento avido e pigro?
Quantificatori avidi (*, +, ?) Afferrare il più possibile e tornare indietro se necessario; quelli pigri (*?, +?, ??) Afferrare il meno possibile ed espandere solo se forzato. in opposizione a <b>bold</b>, avido <.*> ingoia l'intera corda mentre è pigra <.*?> si ferma al primo <b>. Scegliere quello giusto è spesso la soluzione quando un modello corrisponde troppo.
Come faccio a sfuggire ai caratteri speciali nella regex?
Metti una barra rovesciata davanti a qualsiasi metacarattere che intendi letteralmente: \., \*, \+, \?, \(, \), \[, \], \{, \}, \^, \$, \|, e \\. La maggior parte delle lingue offre anche un aiuto per sfuggire a un'intera stringa per te - re.escape() in Python, ad esempio, che è più sicuro che scappare manualmente quando la stringa proviene dall'input dell'utente.
Cosa significano i flag regex G, I e M?
g (Globale) trova ogni partita invece di fermarsi al primo, i (ignorare il caso) rende il modello senza indifferenza e m (multilinea) fa ^ e $ Abbina ad ogni interruzione di riga anziché solo all'inizio e alla fine della stringa. Si combinano liberamente, quindi gim Fa tutti e tre. Un frequente gotcha in JavaScript: riutilizzo a g Regex tra le chiamate trasporta lastIndex tra di loro, che fa test() alterna vero e falso - ricrea il modello o resetta lastIndex.
Cos'è una lookhead in regex?
Uno sguardo in testa afferma che qualcosa non segue o non segue, senza consumarlo. foo(?=bar) fiammiferi foo Solo quando bar viene dopo; foo(?!bar) Corrisponde solo quando non è. Guarda dietro ((?<=...), (?<!...)) fa lo stesso al contrario, ed è approdato nei moderni JavaScript, Python e PCRE - ma non in Go's RE2, che rifiuta entrambi a titolo definitivo Le regole delle password sono l'uso classico: ^(?=.*\d)(?=.*[a-z]).{8,}$ Stack assetazioni in modo che ogni requisito venga controllato in modo indipendente nella stessa posizione.
Come faccio ad abbinare un numero di telefono con regex?
Per un formato specifico, sii esplicito piuttosto che intelligente: ^\(\d{3}\) \d{3}-\d{4}$ fiammiferi (555) 123-4567. Per tollerare vari separatori, consentire quelli opzionali come ^\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$. La numerazione dei telefoni è disordinata tra i vari paesi, quindi convalida solo il formato che effettivamente accetti e normalizzi in cifre prima di memorizzare - costruisci e testa il modello in tempo reale prima di fidarti.
incasso
Regex è passato dalla mia abilità più temuta a una delle mie più usate nel momento in cui ho iniziato a costruire modelli in un live tester invece di indovinare nel mio editore. Inizia in modo semplice, prova contro input reali e contraddittori, rispetta il catastrofico backtracking e mantieni una libreria personale di modelli di cui ti fidi.
la Costruttore di regex su Toolz.dev rende quel ciclo veloce, con la corrispondenza in tempo reale, l'evidenziazione di gruppo e le attivazioni dei flag - tutto in esecuzione nel browser in modo che i dati di test rimangano privati Quando il modello estrae JSON, consegnalo al Formattatore JSON; quando acquisisce un BLOB Base64, decodificalo con il convertitore base64. Oppure sfoglia tutti gli oltre 600 strumenti gratuiti su Toolz.dev.



