Da zero a Esperto Regex
Estrai e analizza stringhe simili a URL con un'unica regex
Indice
- 🚀 Introduzione
- 🔍 Estrazione degli URL dal testo
- 🛳️ La regex da 120+ byte
- 🧩 Analisi passo dopo passo
- 🛠️ Esempio di parsing
- ☑️ Prossimi passi
- 📝 Riepilogo
- 📚 Approfondimenti
TL;DR: Vai direttamente alla regex da 120+ byte.
🚀 Introduzione
Estrarre gli URL da testo grezzo può talvolta sembrare un noioso gioco del molla la talpa. Punteggiatura, parentesi di delimitazione e formattazione ambigua conspirano per vanificare i tuoi tentativi. Che tu stia sviluppando un web scraper, un analizzatore di dati o un’app chat, garantire un’estrazione precisa degli URL è un requisito fondamentale.
In questo post affrontiamo il problema direttamente, adottando un approccio flessibile in due fasi. L’obiettivo è catturare prima tutte le stringhe potenzialmente simili a URL e delegare la validazione a una fase successiva.
💡 Nota: Questo pattern non serve per validare gli URL! È volutamente permissivo con punteggiatura e errori di battitura.
🔍 Obiettivo: Estrarre gli URL dal testo
Quando si estraggono URL da testo grezzo, un approccio in due fasi si dimostra efficace:
- Catturare tutto ciò che assomiglia a un URL: Lanciare una rete ampia per intercettare tutte le stringhe che potrebbero essere URL. È qui che la nostra “regex da oltre 120 byte” mostra il suo valore.
- Validare: Una volta isolati questi candidati, applicare controlli secondari (es. risoluzione DNS, confronto con domini noti) per scartare le voci non valide.
Visualizzare la sfida
I termini extract e parse sono spesso usati in modo intercambiabile, ma indicano processi distinti. L’estrazione di URL consiste nell’identificare e catturare potenziali URL da un testo più ampio. Il parsing, invece, scompone questi URL nelle loro componenti.
Quando parlo di parsing o “componenti di un URL”, mi riferisco a:
Fai clic per vedere uno screenshot del matching delle sottostringhe su RegEx101.
Prima di approfondire la regex, usiamo uno strumento visuale per verificare quanto bene il pattern catturi le corrispondenze:

La regex da oltre 120 byte
Di seguito una regex concisa per estrarre e analizzare gli URL in un’unica operazione. Supporta vari protocolli, domini, percorsi e sezioni query/fragment opzionali.
Non preoccupatevi, lo analizzeremo passo dopo passo!
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;// Compatibility: ES5+
// Same pattern, split on newlines for readability:([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)Condividete le regex più bizzarre che avete incontrato (o scritto) nei commenti qui sotto! 🚀
🧩 Scomposizione passo dopo passo
Analizziamo la regex nei suoi componenti per comprenderne il funzionamento:
1. Protocollo (Gruppo 1): ([-.a-z0-9]+:/{1,3})
- Scopo: Corrisponde alla parte del Protocollo dell’URL (es.
http://,ftp://,custom-scheme://). Spiegazione:
[-.a-z0-9]+: Corrisponde a una o più lettere minuscole, cifre, trattini o punti (tipici degli schemi di protocollo).:/{1,3}: Corrisponde a due punti seguiti da una a tre barre (:/,://o:///).
2. Dominio (Gruppo 2): ([^-/.[](|)s?][^`/s]?]+)
- Scopo: Cattura la parte di Dominio o host dell’URL.
Spiegazione:
[^-/.[](|)\s?]: Corrisponde a qualsiasi carattere eccetto i caratteri speciali specificati e gli spazi bianchi.[^`/\s]?]+: Corrisponde a uno o più caratteri eccetto backtick, barre, spazi bianchi o parentesi quadre di chiusura.
3. Percorso (Gruppo 3): ([-_a-z0-9!@$%^&*()=+;/~\.]*)
- Scopo: Corrisponde alla componente del percorso (path) dell’URL.
Spiegazione:
[-_a-z0-9!@$%^&()=+;/~.]: Corrisponde a zero o più caratteri sicuri per gli URL, comunemente presenti nei percorsi.
4. Query (Gruppo 4): [?]?([^#\s`?]*)
- Scopo: Corrisponde opzionalmente a una stringa di query, iniziando con un carattere
?qualsiasi. Spiegazione:
[?]?: Corrisponde opzionalmente a un?. (Le parentesi quadre non sono strettamente necessarie, ma risultano leggermente più leggibili rispetto al doppio??estremamente compatto. Forniscono inoltre un parallelo visivo per il prossimo gruppo di corrispondenza (simile)[#]?.)([^#\s`?]*): Corrisponde a zero o più caratteri che non siano un cancelletto, spazi bianchi, backtick o punto interrogativo.
5. Fragment (Gruppo 5): [#]?([^#\s’”`.,!]*)
- Scopo: Corrisponde opzionalmente all’identificatore di frammento, iniziando con un
#. Spiegazione:
[#]?: Corrisponde opzionalmente a un#.([^#\s’”`.,!]*): Corrisponde a zero o più caratteri che non siano punteggiatura non consentita o spazi bianchi.
🛠️ Esempio di Parsing
Ecco come puoi sfruttare questa regex mostruosa, con un po’ di JavaScript:
const text = `Check this out: https://example.com/path?query=123#sectionAnd also (ftp://files.server.org/index).Plus a weird one: custom-scheme://host/param;weird^stuff`;
const urlRegex = /([-.a-z0-9]+:\/{1,3})([^-\/\.[\](|)\s?][^`\/\s\]?]+)([-_a-z0-9!@$%^&*()=+;/~\.]*)[?]?([^#\s`?]*)[#]?([^#\s'"`\.,!]*)/gi;
const matches = [ ...text.matchAll(urlRegex),].map((match) => match[0]);console.log("Extracted URLs:", matches);
const parts = [ ...text.matchAll(urlRegex),].map((match) => match.slice(1));console.log("Extracted Parts:", parts);[ "https://example.com/path?query=123#section", "ftp://files.server.org/index", "custom-scheme://host/param;weird^stuff"][ [ "https://", // Protocol "example.com", // Domain "/path", // Path "query=123", // Query "section" // Fragment ], [ "ftp://", // Protocol "files.server.org", // Domain "/index", // Path "", // Query "" // Fragment ], [ "custom-scheme://", // Protocol "host", // Domain "/param;weird^stuff", // Path "", // Query "" // Fragment ]]☑️ Passi successivi
A seconda del caso d’uso, potresti dover affinare questa regex o integrare ulteriori passaggi di validazione e post-elaborazione.
Progetti diversi, esigenze diverse
I progetti presentano requisiti e preoccupazioni per la sicurezza variabili:
- Web Scraping: Validare gli URL per garantirne la raggiungibilità e l’affidabilità.
- Elaborazione Dati: Estrarre gli URL dai contenuti generati dagli utenti applicando filtri di sicurezza.
- Analisi Dati: Scartare duplicati o link irrilevanti per finalità di ricerca o marketing.
- Applicazioni per l’Utente: Generare automaticamente link ipertestuali per gli URL in app di chat o forum.
Post-elaborazione e Validazione
Una volta raccolte le corrispondenze potenziali, applicare controlli supplementari:
- Risoluzione DNS: Verificare la corretta risoluzione dei domini.
- Controlli di Sicurezza: Utilizzare servizi di threat intelligence per verificare la reputazione dei domini e ridurre il rischio di esposizione a siti malevoli o di phishing.
- Regole Personalizzate: Applicare filtri specifici del progetto (es. TLD consentiti, lunghezza massima dell’URL).
📝 Riepilogo
Estrarre dati testuali semi-strutturati è probabilmente la parte più soddisfacente del dominio delle regex.
Ecco un riepilogo dei punti chiave:
- Utilizza uno strumento visuale per scrivere, testare e comprendere i tuoi pattern Regex.
- Scomponi la sfida in parti e risolvi ciascun blocco separatamente. In un certo senso, i gruppi di cattura fungono da veri e propri ‘segnavia’ per la nostra regex.
- Adotta espressioni di matching permissive, evitando un’aderenza rigida alle specifiche durante l’ingestione dei dati.
- Applicare passaggi di validazione dopo l’estrazione iniziale è fondamentale: valuta sempre la sicurezza del progetto e i requisiti specifici.
Seguendo questa procedura, puoi estrarre efficacemente qualsiasi dato testuale semi-strutturato, gettando le basi per elaborazioni e validazioni successive.
📚 Approfondimenti
- Sperimenta con il demo live su RegEx101.com!
- Domanda originale su StackOverflow e link alla mia risposta qui.
- Documentazione MDN sulle Espressioni Regolari
- Tecniche Regex Avanzate: Esplora lookahead, lookbehind e pattern avanzati per un matching più preciso.
- RFC 3986 - Sintassi Generica URI