Corso Python / Espressioni regolari con re: ricerca e validazione

Un’espressione regolare cerca una sequenza di caratteri o verifica se una stringa rispetta una forma. Trovare una corrispondenza non dimostra però che una data esista o che un importo sia valido per l’applicazione: separa ricerca, conversione e controllo del significato.

Scegliere tra ricerca e corrispondenza completa

Funzione Domanda a cui risponde
re.search Esiste una parte corrispondente in qualche punto della stringa?
re.fullmatch L’intera stringa corrisponde al modello?
re.finditer Quali corrispondenze successive, non sovrapposte, e relative posizioni si trovano?

Per estrarre diversi record da un testo libero, finditer è adatto a percorrere le corrispondenze. Per accettare un singolo valore inserito in un modulo, fullmatch evita invece che un frammento valido nasconda caratteri estranei prima o dopo. La scelta dipende dall’interfaccia che stai realizzando.

Le stringhe raw, come r"...", rendono più chiara la distinzione tra gli escape delle stringhe Python e quelli del modello. Restano comunque stringhe Python, con vincoli come l’impossibilità di terminare un letterale raw con un singolo backslash non bilanciato. La documentazione ufficiale di re descrive sintassi e funzioni.

Estrarre campi con nome e interpretare una data

Salva il programma completo come regex_demo.py, in UTF-8, in una cartella di esercizio. Esegui python regex_demo.py nel terminale con l’interprete del progetto selezionato. Fuori dall’ambiente virtuale su macOS o Ubuntu usa python3 se è il comando scelto. Re e datetime appartengono alla libreria standard.

import re
from datetime import date

text = "A001:3500 B002:8000"
pattern = re.compile(r"(?P<id>[A-Z][0-9]{3}):(?P<amount>[0-9]+)")
for match in pattern.finditer(text):
    print(match["id"], int(match["amount"]))
value = "2026-10-17"
if re.fullmatch(r"[0-9]{4}-[0-9]{2}-[0-9]{2}", value):
    print(date.fromisoformat(value))

Il risultato previsto è:

A001 3500
B002 8000
2026-10-17

Il modello richiede una lettera ASCII maiuscola, tre cifre ASCII, il carattere due punti e una o più cifre per l’importo. I gruppi con nome id e amount permettono di recuperare i campi senza ricordarne soltanto la posizione numerica. Il gruppo amount è ancora testo e viene convertito con int prima della stampa.

[0-9] esprime qui una scelta precisa delle cifre ammesse. Non sostituirlo automaticamente con altre classi pensando che ogni modello abbia la stessa politica sui caratteri Unicode. Compile prepara un oggetto modello riutilizzabile; le funzioni di modulo offrono anche scorciatoie quando non serve conservarlo.

Gestire assenza di corrispondenze e valori senza significato

Search restituisce None quando non trova nulla. Prima di leggere group o un gruppo con nome, verifica che la corrispondenza esista, per esempio con if match is not None:. Chiamare group su None genera AttributeError e non significa che il modello abbia trovato un campo vuoto.

Il modello della data controlla soltanto quattro cifre, trattino, due cifre, trattino e due cifre. Una stringa come 2026-02-30 o 2026-99-99 ha quella forma ma non è una data valida. date.fromisoformat esegue il controllo di calendario e può sollevare ValueError, come nella guida a date e fusi orari. L’esempio non intercetta quell’errore: il suo arresto è ciò che osserverai nella prova della data impossibile.

La ricerca dei record non controlla l’intero testo né i confini di ciascun token. Per esempio, dentro un testo più lungo può individuare A001:3500 anche se è preceduto da una lettera o seguito da altri caratteri. Con un importo come 3500.5 può trovare soltanto la parte 3500. È un comportamento di estrazione, non la conferma che il valore completo sia un intero valido.

Per dati con una grammatica specifica usa il parser appropriato. Il modulo csv gestisce campi citati e separatori nella lezione sui CSV; un parser HTML tratta la struttura del documento. Non sostituire l’intero parser di questi formati con un’unica espressione regolare improvvisata.

Limitare l’ingresso e confrontare le condizioni

Un modello con ripetizioni complesse e un ingresso molto lungo può richiedere tempi di elaborazione eccessivi. Mantieni controllati i modelli che esegui e scegli limiti di lunghezza adeguati per i dati esterni. Non accettare automaticamente espressioni arbitrarie come se fossero semplici testi senza costo di esecuzione.

  1. Nel testo dell’esempio cambia soltanto A001 in a001. Il primo record non deve essere estratto; B002 e la data restano visibili.
  2. Ripristina l’identificatore e cambia soltanto il suo importo in -1. Anche in questo caso il primo record non corrisponde: il modello non include il segno meno.
  3. In una prova separata cambia la data in 2026-02-30. La forma passa fullmatch ma il controllo di calendario deve fallire con ValueError.
  4. Ripristina tutti i valori e verifica nuovamente le tre righe originali.

Se l’obiettivo diventa validare una sola coppia identificatore–importo, usa una verifica dell’intero ingresso e stabilisci anche limiti numerici e politica sugli errori. Estrarre qualche campo valido da un testo e approvare tutto quel testo sono operazioni diverse.