In questo articolo spiegherò come utilizzare le espressioni regolari in Python per estrarre date e orari dai dati di testo. Le espressioni regolari sono uno strumento potente che consente di rilevare in modo efficiente stringhe con un formato specifico attraverso il pattern matching. Tratteremo le basi delle espressioni regolari, passando attraverso applicazioni più avanzate, e mostreremo come abbinare date e orari con precisione in Python, con esempi concreti.
Cosa sono le espressioni regolari
Le espressioni regolari (Regular Expression) sono stringhe speciali utilizzate per definire pattern in altre stringhe. Vengono usate per esprimere combinazioni o ripetizioni di caratteri, e vengono impiegate nella ricerca, sostituzione ed estrazione di stringhe. Sono ampiamente utilizzate in programmazione e nell’elaborazione del testo, rappresentando uno strumento potente per manipolare i dati in modo efficiente e flessibile.
Modulo delle espressioni regolari di Python
In Python, il modulo standard per lavorare con le espressioni regolari è il modulo «re». Questo modulo consente di eseguire facilmente operazioni di ricerca, sostituzione, divisione e matching delle stringhe. Di seguito presenteremo le modalità di utilizzo di base e le principali funzioni di questo modulo.
Utilizzo di base
Per utilizzare le espressioni regolari, prima di tutto bisogna importare il modulo «re». Successivamente, si crea il pattern dell’espressione regolare e si utilizzano le sue funzioni per manipolare le stringhe.
import re
# Compilare il pattern dell'espressione regolare
pattern = re.compile(r'\d{4}-\d{2}-\d{2}')
# Eseguire il matching
match = pattern.match('2023-06-16')
if match:
print("Match trovato:", match.group())
Funzioni principali
re.match()
: Controlla se l’inizio di una stringa corrisponde al pattern.re.search()
: Cerca l’intera stringa e restituisce il primo match trovato.re.findall()
: Restituisce una lista di tutte le sottostringhe che corrispondono al pattern.re.sub()
: Sostituisce le sottostringhe che corrispondono al pattern.
Matching delle date
Per fare il matching delle date, l’espressione regolare cambia in base al formato della data. In questo esempio vedremo come fare il matching di un formato di data comune, ovvero «YYYY-MM-DD». Questo formato è composto da anno (4 cifre), mese (2 cifre) e giorno (2 cifre).
Matching di una data di base
Il seguente pattern dell’espressione regolare fa il matching di una data nel formato «YYYY-MM-DD».
import re
# Creare il pattern dell'espressione regolare
date_pattern = re.compile(r'\b\d{4}-\d{2}-\d{2}\b')
# Testo di esempio
text = "La data di oggi è 2023-06-16."
# Eseguire il matching
matches = date_pattern.findall(text)
if matches:
print("Data trovata:", matches)
else:
print("Data non trovata.")
Questo pattern corrisponde a 4 cifre numeriche (\d{4}), seguite da un trattino (-), 2 cifre numeriche (\d{2}), un altro trattino e infine altre 2 cifre numeriche (\d{2}). L’uso di \b
indica il confine della parola, assicurando che non ci siano altri caratteri prima o dopo la data.
Esempio avanzato: matching di più formati di data
Per fare il matching di più formati di data, è possibile combinare vari pattern. Ad esempio, per includere anche i formati «YYYY/MM/DD» o «YYYY.MM.DD», si può fare come segue.
# Combinazione di più pattern
date_pattern = re.compile(r'\b\d{4}[-/\.]\d{2}[-/\.]\d{2}\b')
# Testo di esempio
text = "Le date sono 2023-06-16, ieri 2023/06/15 e domani 2023.06.17."
# Eseguire il matching
matches = date_pattern.findall(text)
if matches:
print("Data trovata:", matches)
else:
print("Data non trovata.")
Questo pattern riconosce i trattini (-), le barre (/) e i punti (.) come delimitatori.
Matching degli orari
Le espressioni regolari per fare il matching degli orari cambiano a seconda del formato dell’orario. In questo esempio, vedremo come fare il matching di un formato orario comune «HH:MM:SS», composto da ore (2 cifre), minuti (2 cifre) e secondi (2 cifre).
Matching di un orario di base
Il seguente pattern dell’espressione regolare fa il matching di un orario nel formato «HH:MM:SS».
import re
# Creare il pattern dell'espressione regolare
time_pattern = re.compile(r'\b\d{2}:\d{2}:\d{2}\b')
# Testo di esempio
text = "L'orario corrente è 14:30:45."
# Eseguire il matching
matches = time_pattern.findall(text)
if matches:
print("Orario trovato:", matches)
else:
print("Orario non trovato.")
Questo pattern corrisponde a 2 cifre numeriche (\d{2}), seguite dai due punti (:), altre 2 cifre numeriche, altri due punti e altre 2 cifre numeriche. L’uso di \b
indica il confine della parola, assicurando che non ci siano altri caratteri prima o dopo l’orario.
Esempio avanzato: matching di orari in formato 24 ore e 12 ore
Per fare il matching di orari sia in formato 24 ore che in formato 12 ore, bisogna includere la gestione di AM/PM.
# Matching per formato 24 ore e 12 ore
time_pattern = re.compile(r'\b((1[0-2]|0?[1-9]):[0-5][0-9](\s?[APap][Mm])?|([01][0-9]|2[0-3]):[0-5][0-9])\b')
# Testo di esempio
text = "L'orario corrente è 14:30, la riunione del mattino è alle 10:00 AM, e quella pomeridiana alle 02:00 PM."
# Eseguire il matching
matches = time_pattern.findall(text)
if matches:
print("Orari trovati:", [match[0] for match in matches])
else:
print("Orario non trovato.")
Questo pattern riconosce i seguenti formati di orario:
- Orari in formato 24 ore (ad esempio: 14:30)
- Orari in formato 12 ore (ad esempio: 10:00 AM, 02:00 PM)
Esempio avanzato: conversione di formato di data e orario
In questo esempio vedremo come estrarre una data e un orario usando le espressioni regolari e poi convertirli in un formato differente. Convertemo il formato «YYYY-MM-DD HH:MM:SS» in «MM/DD/YYYY hh:mm AM/PM».
Estrazione di data e orario
Per prima cosa, estraiamo la data e l’orario dal testo usando le espressioni regolari.
import re
# Creare il pattern dell'espressione regolare
datetime_pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})')
# Testo di esempio
text = "L'evento inizia il 2023-06-16 14:30:45."
# Eseguire il matching
match = datetime_pattern.search(text)
if match:
year, month, day, hour, minute, second = match.groups()
print("Data e orario estratti:", match.group())
else:
print("Data e orario non trovati.")
Implementazione della conversione del formato
Ora converte la data e l’orario estratti nel formato «MM/DD/YYYY hh:mm AM/PM».
# Determinare AM/PM
hour = int(hour)
if hour >= 12:
period = "PM"
if hour > 12:
hour -= 12
else:
period = "AM"
if hour == 0:
hour = 12
# Convertire al nuovo formato
formatted_datetime = f"{month}/{day}/{year} {hour:02}:{minute} {period}"
print("Data e orario convertiti:", formatted_datetime)
Questo codice converte un orario in formato 24 ore in formato 12 ore e aggiunge AM/PM per generare il nuovo formato.
Esercizi: Estrazione di date e orari
Per approfondire la comprensione delle espressioni regolari, proviamo a risolvere alcuni esercizi. Lavorando su questi esempi, potrai acquisire esperienza pratica con le espressioni regolari.
Esercizio 1: Estrazione di una singola data
Creare un’espressione regolare per estrarre una data nel formato «YYYY-MM-DD» dal seguente testo.
text = "La scadenza è il 2024-07-20. Il progetto è iniziato il 2024-06-01."
Soluzione
import re
date_pattern = re.compile(r'\b\d{4}-\d{2}-\d{2}\b')
dates = date_pattern.findall(text)
print("Date estratte:", dates)
Esercizio 2: Estrazione di più orari
Creare un’espressione regolare per estrarre tutti gli orari nel formato «HH:MM:SS» dal seguente testo.
text = "La colazione è alle 07:30:00, il pranzo alle 12:00:00, la cena alle 19:45:00."
Soluzione
import re
time_pattern = re.compile(r'\b\d{2}:\d{2}:\d{2}\b')
times = time_pattern.findall(text)
print("Orari estratti:", times)
Esercizio 3: Estrazione della data e dell’orario e conversione del formato
Estrai la data e l’orario nel formato «YYYY-MM-DD HH:MM:SS» dal testo seguente e convertilo nel formato «MM/DD/YYYY hh:mm AM/PM».
text = "La riunione inizierà il 2024-06-16 14:30:45."
Soluzione
import re
# Creare il pattern dell'espressione regolare
datetime_pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})')
# Eseguire il matching
match = datetime_pattern.search(text)
if match:
year, month, day, hour, minute, second = match.groups()
# Determinare AM/PM
hour = int(hour)
if hour >= 12:
period = "PM"
if hour > 12:
hour -= 12
else:
period = "AM"
if hour == 0:
hour = 12
# Convertire al nuovo formato
formatted_datetime = f"{month}/{day}/{year} {hour:02}:{minute} {period}"
print("Data e orario convertiti:", formatted_datetime)
else:
print("Data e orario non trovati.")
Errori comuni e soluzioni
Durante l’uso delle espressioni regolari, è possibile imbattersi in alcuni errori comuni. Comprendere questi errori e affrontarli correttamente permette di migliorare l’accuratezza e l’efficienza delle espressioni regolari.
Errore 1: Matching troppo “avidità”
Il matching “avidità” (greedy matching) cerca di abbinare la stringa più lunga possibile, il che può portare a risultati indesiderati.
Soluzione: utilizzare il matching non avidità
Usare il matching non avidità (lazy matching) per abbinare solo la parte necessaria della stringa. Utilizzare *?
o +?
per rendere il matching non avidità.
import re
text = "Start123End456End"
pattern = re.compile(r'Start.*?End')
matches = pattern.findall(text)
print("Matching non avidità:", matches)
Errore 2: Uso errato dei caratteri di escape
Se si utilizzano caratteri con un significato speciale nelle espressioni regolari (come .
o *
), questi potrebbero non comportarsi come ci si aspetta.
Soluzione: usare correttamente i caratteri di escape
Per utilizzare i caratteri speciali come normali caratteri, bisogna fare uso del backslash (\
) per l’escape.
import re
text = "Il nome del file è example.txt."
pattern = re.compile(r'example\.txt')
matches = pattern.findall(text)
print("Uso del carattere di escape:", matches)
Errore 3: Diminuzione delle performance dovuta alla complessità del pattern
Pattern complessi possono ridurre le performance e aumentare il tempo di esecuzione.
Soluzione: ottimizzare il pattern
Creare pattern semplici ed efficienti per migliorare le performance. Evitare gruppi di cattura inutili e cercare di abbinare solo ciò che è strettamente necessario.
import re
# Pattern complesso
complex_pattern = re.compile(r'(\d{1,4})-?(\d{1,2})-?(\d{1,2})')
# Pattern ottimizzato
optimized_pattern = re.compile(r'\d{1,4}-\d{1,2}-\d{1,2}')
Errore 4: Malintesi nei risultati del matching
Se non si comprendono correttamente i risultati del matching delle espressioni regolari, potrebbero esserci fraintendimenti nei dati estratti.
Soluzione: usare gli oggetti di matching
Usare gli oggetti di matching per ottenere esattamente le sottostringhe e i gruppi di cattura abbinati.
import re
text = "La data di oggi è 2024-07-20."
pattern = re.compile(r'(\d{4})-(\d{2})-(\d{2})')
match = pattern.search(text)
if match:
year, month, day = match.groups()
print(f"Data estratta: Anno={year}, Mese={month}, Giorno={day}")
else:
print("Data non trovata.")
Conclusioni
Le espressioni regolari sono uno strumento potente per abbinare in modo efficiente stringhe con formati specifici, come date e orari. Utilizzando il modulo «re» di Python, è possibile eseguire operazioni complesse su stringhe in modo semplice ed efficace. In questo articolo abbiamo visto l’utilizzo di base delle espressioni regolari, il matching delle date e degli orari, esempi avanzati, esercizi pratici e come affrontare errori comuni. Usare correttamente le espressioni regolari può migliorare notevolmente l’accuratezza e l’efficienza nel trattamento dei dati.