Seguici su Telegram, ne vale la pena ❤️ ➡ @trovalost
Vai al contenuto

Guida pratica alle espressioni regolari

Le regex sono il classico argomento di informatica che è difficilmente comprensibile se non viene utilizzato in un contesto reale almeno una volta nella vita. Le espressioni regolari o regex rappresentano infatti dei pattern di testo, ovvero un insieme di più stringhe, frasi o combinazioni delle stesse che è possibile generare per esteso a parte da esse. Una regex non è altro se non una Regular Expression, e contrariamente a quello che si sente dire in giro non servono solo ai programmatori (soprattutto per validare i form, ad esempio): sono utili anche a chi usa Google Analytics, ad esempio, e si possono usare per effettuare editing di testo avanzato in modo veloce oppure, ancora, si possono usare dentro Excel. In molti esempi faremo riferimento alle regex per PHP, ma ciò non toglie che gli esempi si possano estendere anche altrove.

A che servono le regex

Le espressioni regolari, o regex, sono sequenze di caratteri che definiscono un pattern di ricerca. Sono ampiamente utilizzate per trovare, manipolare e sostituire testo all’interno di stringhe. Puoi utilizzarle in molti linguaggi di programmazione, come Python, JavaScript, Java e molti altri. Ecco alcuni modi comuni in cui le regex vengono utilizzate:

  1. Ricerca di testo: Puoi utilizzare le regex per cercare un pattern specifico all’interno di una stringa. Ad esempio, per trovare tutte le occorrenze di “cane” in una stringa.
  2. Validazione di input: Le regex sono utili per validare che un input rispetti un certo formato. Ad esempio, un’email deve seguire un formato specifico con un “@” e un dominio valido.
  3. Sostituzione di testo: Puoi utilizzare le regex per sostituire parti di una stringa che corrispondono a un certo pattern con un altro testo. Ad esempio, puoi sostituire tutte le occorrenze di “gatto” con “cane” in una stringa.
  4. Estrazione di informazioni: Puoi estrarre parti specifiche di una stringa che corrispondono a un certo pattern. Ad esempio, estrarre tutti i numeri da una stringa.
  5. Filtraggio di dati: Puoi utilizzare le regex per filtrare dati basati su determinati criteri. Ad esempio, filtrare una lista di indirizzi email per trovare solo quelli che appartengono a un certo dominio.

L’uso pratico delle regex dipende dal linguaggio di programmazione che stai utilizzando. In genere, ogni linguaggio ha una libreria incorporata o disponibile che fornisce supporto per le regex. Consulta la documentazione del linguaggio che stai utilizzando per informazioni dettagliate su come utilizzare le regex in quel contesto.

Riconoscere indirizzi IP con le regex

L’esempio più classico che si può pensare riguarda il riconoscimento di indirizzi IP: supponete di essere l’amministratore di una rete, e di avere bisogno, ad un certo punto, di validare un campo della vostra form nel quale l’utente finale inserirà  l’indirizzo numerico del tipo 192.168.1.4 o simili. Per assicurarci che il campo che viene inserito sia davvero in indirizzo IP e non una sequenza differenze di caratteri, una regex è proprio ciò che fa al caso nostro.

E’ chiaro anche che non tutte le sequenze di 4 numeri aaa.bbb.ccc.ddd sono valide: la regola fondamentale e più generale possibile vuole che le 4 cifre siano comprese tra 0 e 255. Per indicare un numero compreso tra 0 e 255, come regex scriviamo cosà¬:

(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

dove in sostanza [0-5] rappresenta una cifra qualsiasi tra 0 e 5, mentre il ? indica che quanto scritto poco prima deve essere presente almeno una volta. A questo punto, il riconoscimento (o più correttamente la validazione di questo campo stringa) può essere effettuato con questa espressione compatta:

b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b

A prima vista si tratta di aramaico puro, vero? Niente paura. Scomponendola (l’unico modo per capire le regex è proprio questo, visto che si tratta di “cose” complicate composte da tanti pezzetti semplici) ci accorgiamo che è composta da tanti “pezzi” tra parentesi quadre che ricorrono in continuazione: ognuno di essi rappresenta una classe di caratteri, nello specifico dei numeri da 0 a 5 o da 0 a 4 e via dicendo… che possono in alcuni casi comparire o meno almeno una volta (cosiddetto quantificatore rappresentato da ?).

Come funzionano le espressioni regolari in generale

Anzitutto bisogna sapere che un’espressione regolare è fatta di meta-caratteri, ovvero caratteri che rappresentano “entità “, che non necessariamente coincidono con quello che viene scritto, ma che rappresentano dei caratteri generalizzati, ad esempio di un certo tipo (un set di lettere come (a,b,g), o dei numeri).

Ancore di inizio e fine pattern: ^ e $

Per delimitare l’inizio e la fine di un pattern, si può sfruttare il carattere iniziale ^ e quello finale $.

^Sto - qualsiasi stringa che inizia con "Sto"
zzo$ - qualsiasi stringa che finisce con "zzo"

Quantificatori — * + ? {}

I quantificatori servono a definire quante volte un carattere o un simbolo deve essere ripetuto (eventualmente anche “almeno una volta” col simbolo +).

abc*        stringa che inizia esattamente con ab ed è seguita da una c, che potrebbe mancare
abc+        stringa che inizia esattamente con ab ed è seguita da almeno una c
abc?        stringa del tipo ab oppure abc
abc{2}      stringa con ab all'inizio e poi c ripetuta esattamente due volte
abc{2,}     stringa con ab all'inizio e poi c ripetuta almeno due volte
abc{2,5}    stringa con ab all'inizio e poi c ripetuta da due a cinque volte
a(bc)*      stringa a seguita da bc (che potrebbe anche mancare, quindi matcha con: abc e a)
a(bc){2,5}  stringa a seguita da bc da 2 a cinque volte, per cui: abcbc, abcbcbc, ... abcbcbcbcbc.

OR — | or []

a(b|c)     match con ab oppure ac  

Classi di caratteri

\d una cifra

\w una parola

\s uno spazio di qualsiasi genere

\D qualsiasi carattere che non sia una cifra

\W qualsiasi carattere che non sia una parola

\S qualsiasi carattere che non sia uno spazio di qualsiasi genere

Flag (usate in Javascript e PHP)

Le flag servono a delimitare l’espressione regolare, e si possono usare anche senza ” (doppi apici).

Esempi:

/abc/ indica la sequenza abc

/abc/i indica la sequenza abc case insensitive (sia AbC che ABC che ABc ecc.)

Gruppi

Non voglio sembrare mistico o astratto, a questo punto: voglio soltanto esprimere che posso avere dei meta-caratteri che rappresentano “gruppi” o “sequenze” jolly, per cosଠdire, di possibili stringhe. Invece di scrivere “verifica che sia un numero tra 0 e 9” scriverò in meta-caratteri semplicemente la “dichiarazione” [0-9], dove le parentesi quadre indicano un gruppo.

Pattern e quantificatori

Notiamo poi che scrivere (.)+ significa esprimere un pattern, ovvero far capire al linguaggio che con quell’espressione vogliamo catturare tutte le stringhe di lunghezza almeno 1 di qualsiasi caratteri (da cui deriva il +). Quindi . rappresenta (nelle regex cosiddette POSIX usate da PHP, in particolare) un numero qualunque di caratteri di cardinalità  (numero di caratteri) almeno uno.

Quindi un generico (.)+ puo’ rappresentare varie stringhe corrispondenti:

f

asg

1265763

bads

sjhdjha

salvatore capolupo

ma non, ad esempio, la stringa vuota perchè + esprime il fatto che la stringa sia di almeno un carattere. Se invece scrivo (.)? dico che la mia stringa qualsiasi potrebbe anche essere vuota (come un campo “non richiesto” del modulo di iscrizione di una form).

Validare un indirizzo email con una regex

Vediamo di comprendere come riconoscere un indirizzo e-mail: la sua struttura più generale possibile sarà , ad esempio, del tipo [email protected]. Quello che dovremo fare è:

1) far capire all’interprete che @ e . sono caratteri “letterali” e non meta-caratteri (altrimenti ci sarebbe ambiguità ), e

2) esprimere “genericamente” username e address e est.

In altri termini potremmo scrivere:

(.)+@(.)+.(.){3}

dove (.)+ ha lo stesso significato di prima, @ e . indicano i caratteri @ e . e (.){3} indica una sequenza di caratteri lunga, per semplificare, esattamente tre (potremmo avere infatti com, net, ma non it, ad esempio). Dovrebbe essere tutto un po’ più chiaro, spero.

A questo punto la composizione di un indirizzo IP xxx.xxx.xxx.xxx si può suddividere in 4 numeri separati dal punto:

(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

Le alternative sono separate dal meta-carattere |, cioè stiamo dicendo che un singolo numero di un IP può essere dato da:

  • 25[0-5] ovvero ’25’ seguito da un numero qualsiasi compreso tra 0 e 9 (250,251,…,255)
  • 2[0-4][0-9] ovvero ‘2’ seguito da una cifra tra 0 e 4 ed una cifra tra 0 e 9 (247, 209, ecc.)
  • [01]?[0-9][0-9] ovvero uno 0 o un 1 (che possono mancare, dato che sono seguiti da ?), seguito da due cifre qualsiasi tra 0 e 9 (17, 124, ecc.)

L’indirizzo IP,in definitiva, sarà  dato da una concatenazione di 4 volte questo pattern, che accetterà  dunque stringhe tipo: 255.255.0.0 ma non 256.11.17.27 (il 256 è fuori range). L’argomento è difficile (almeno all’inizio) ma molto appassionante per quanto mi riguarda, e soprattutto ricordiamo che non è fine a se stesso perchè viene utilizzato nella comune programmazione PHP come nella sintassi dei file htaccess di Apache.

Ecco alcuni esempi di espressioni regolari in PHP, C++ e Python.

Regex PHP

php
<?php
// Esempio di ricerca di una parola in una stringa
$stringa = "Questo è un esempio di testo contenente la parola cane.";
if (preg_match("/cane/", $stringa)) {
echo "La parola 'cane' è stata trovata nella stringa.";
}
else {
echo "La parola 'cane' non è stata trovata nella stringa.";
}
?>

Regex C++

#include <iostream>
#include <regex>
using namespace std;



int main() {
// Esempio di ricerca di una parola in una stringa
string testo = "Questo è un esempio di testo contenente la parola cane.";
regex pattern("cane");
if (regex_search(testo, pattern)) {
cout << "La parola 'cane' è stata trovata nella stringa." << endl;
} else {
cout << "La parola 'cane' non è stata trovata nella stringa." << endl;
}
return 0;
}

Regex in Python

import re

# Esempio di ricerca di una parola in una stringa
testo = "Questo è un esempio di testo contenente la parola cane."
if re.search(r'cane', testo):
print("La parola 'cane' è stata trovata nella stringa.")
else:
print("La parola 'cane' non è stata trovata nella stringa.")

Questi esempi mostrano come utilizzare le espressioni regolari per cercare una parola specifica (“cane”) all’interno di una stringa. Ovviamente, le espressioni regolari possono essere molto più complesse e flessibili, consentendo di definire pattern dettagliati per la ricerca, la sostituzione, l’estrazione e altre operazioni.

👇 Da non perdere 👇



Questo sito web esiste da 4461 giorni (12 anni), e contiene ad oggi 6471 articoli (circa 5.176.800 parole in tutto) e 12 servizi online gratuiti. – Leggi un altro articolo a caso
5/5 (1)

Ti sembra utile o interessante? Vota e fammelo sapere.

Questo sito contribuisce alla audience di sè stesso.
Il nostro network informativo: Lipercubo.it - Pagare.online - Trovalost.it.