Tutorial di espressione regolare del Python

Jinku Hu 11 dicembre 2023
  1. Espressione regolare di Python re.match() Funzione
  2. Funzione di espressione regolare Python re.search() di Python
  3. Compilare espressioni regolari con re.complie
  4. Flags nel modulo re di espressione regolare Python
  5. Controllo dei caratteri ammessi
  6. Cerca e sostituisci
  7. La funzione findall()
  8. La funzione finditer()
  9. La funzione split()
  10. Gli schemi di base di re
  11. Casi di ripetizione
  12. Ripetizione Nongreedy
  13. Caratteri speciali e sequenze in re
  14. La funzione escape
  15. La funzione group()
Tutorial di espressione regolare del Python

In questo tutorial, imparerete le espressioni regolari e le operazioni di espressione regolare definite nel modulo re in Python. re è la libreria standard di Python che supporta le operazioni di matching delle espressioni regolari.

L’espressione regolare in Python è un insieme di caratteri o sequenza che viene usato per far corrispondere una stringa ad un altro schema usando una sintassi formale. Si potrebbe pensare alle espressioni regolari come ad un piccolo linguaggio di programmazione che è incorporato in Python.

Si può usare l’espressione regolare per definire alcune regole e queste regole sono poi usate per creare possibili stringhe dalla stringa data con cui si vuole far corrispondere il pattern. Le espressioni regolari in Python sono interpretate come un insieme di istruzioni.

Espressione regolare di Python re.match() Funzione

È possibile utilizzare la funzione match per far corrispondere il pattern RE con la stringa data. La funzione match contiene delle bandiere. I flag definiscono il comportamento di un’espressione regolare e possono contenere diversi valori che vedrete più avanti in questo tutorial.

La seguente è la sintassi della funzione match in Python:

re.match(pattern, string, flags)

Ha tre argomenti,

  1. pattern è il modello di espressione regolare che deve essere abbinato
  2. string è la stringa data che deve essere abbinata con l’espressione regolare
  3. Le flags sono usate per cambiare il comportamento dell’espressione regolare, ed è facoltativo.

Se la corrispondenza viene eseguita con successo l’oggetto match sarà restituito altrimenti None sarà restituito. L’oggetto match ha altri due metodi principali che sono le funzioni group(num) e group(). Lo scopo principale per utilizzare queste funzioni è quello di restituire rispettivamente la corrispondenza o una specifica succursale e tutte le successioni.

Utilizzando la funzione re.match

L’esempio seguente mostra come si può utilizzare la funzione match:

import re

strTest = "Hello Python Programming"
mobj = re.match(r"hello", strTest, re.I)
print(mobj.group())

In questo codice viene prima di tutto importato il modulo re. Poi si confronterà una stringa strTest con il pattern RE e il valore restituito dalla funzione match sarà assegnato a mobj. La funzione match è chiamata usando re, quindi tra parentesi il primo argomento è il pattern da abbinare, e poi si avrà la stringa data da cui il pattern sarà abbinato e si passerà anche un valore di flag. Qui re.I è il valore del flag che significa IGNORECASE, quindi verrà ignorato se lo schema e la stringa hanno lettere maiuscole o minuscole diverse.

L’output è :

Hello

In questo esempio, viene usato il prefisso r che dice che la stringa è una stringa grezza. In una stringa grezza non c’è bisogno di scrivere doppi schizzi quando si usano sequenze di escape, per esempio se si vuole un backslash, allora si ha solo un singolo \ ma non doppi schizzi \ come nelle stringhe normali. Questa è l’unica differenza tra una stringa normale e una stringa grezza.

Usando la funzione re.match con una stringa normale

Si consideri l’esempio seguente in cui viene utilizzata una stringa regolare al posto di una stringa grezza:

import re

str = "\\tHello Python Programming"
mobj = re.match("\\thello", str, re.I)  # no match

str = "\tHello Python Programming"
mobj = re.match("\\thello", str, re.I)  # \thello is matching

Funzione di espressione regolare Python re.search() di Python

Si può usare la funzione re.search() per cercare il pattern RE nella stringa data. La funzione search contiene tre argomenti nella funzione il pattern, data string, e flags (opzionale) rispettivamente.

La seguente è la sintassi della funzione di ricerca in Python:

re.search(pattern, string, flags)

Il seguente codice Python dimostra l’uso della funzione search():

import re

str = "Hello Python Programming"
sobj = re.search(r"programming", str, re.I)
print(sobj.group())
Programming

In questo codice viene effettuata la ricerca della parola programmazione. La funzione search cerca in tutta la stringa. La differenza tra ricerca e match è che la funzione match controlla solo all’inizio della stringa, mentre la ricerca search cerca nell’intera stringa.

Ricerca all’inizio usando re.search

Se si vuole cercare all’inizio della stringa, allora si può usare ^. Consideriamo il seguente esempio:

import re

str = "Hello Python Programming"
sobj = re.search(r"^programming", str, re.I)
print(sobj.group())  # no match is found

sobj = re.search(r"^hello", str, re.I)
print(sobj.group())  # matching: Hello

Qui ^ effettuerà la ricerca solo all’inizio della stringa.

Ricerca alla fine utilizzando re.search

Si può anche cercare alla fine della stringa data. Può essere fatta usando $ alla fine dello schema. Considerate il codice qui sotto:

import re

str = "Hello Python Programming"
sobj = re.search(r"programming$", str, re.I)
print(sobj.group())  # matching: Programming

sobj = re.search(r"hello$", str, re.I)
print(sobj.group())  # no match found

Compilare espressioni regolari con re.complie

Le espressioni regolari in Python quando vengono compilate vengono convertite in modelli. Questi patterns sono in realtà gli oggetti pattern che contengono diverse funzioni per eseguire diversi compiti che possono includere la ricerca, la corrispondenza, e la sostituzione, ecc.

Quando si compila un pattern, allora si può usare quel pattern in seguito nel programma.

Utilizzo di modelli precompilati

Si consideri il codice sottostante in cui viene compilato lo schema r"\d" che significa la prima cifra della stringa e poi usato questo schema per chiamare la funzione di ricerca e passato una stringa nella funzione di ricerca. Questo schema verrà cercato nella stringa fornita per la funzione di ricerca. Allo stesso modo, si può usare questo pattern precompilato con la funzione match come segue:

import re

compPat = re.compile(r"(\d)")
sobj = compPat.search("Lalalala 123")
print(mobj.group())

mobj = compPat.match("234Lalalala 123456789")
print(mobj.group())
1
2

Flags nel modulo re di espressione regolare Python

È possibile utilizzare i flag per modificare il comportamento di un’espressione regolare. In una funzione, le bandiere sono opzionali. Si possono usare i flag in due modi diversi, ovvero usando la parola chiave flags e assegnandole il valore del flag oppure scrivendo direttamente il valore del flag. Si può avere più di un valore di flag nel RE letterale; questo può essere fatto usando l’operatore bitwise OR |.

Si consideri la seguente tabella in cui alcuni dei flag comunemente usati sono descritti con i letterali di espressione regolare:

Valore del flag Descrizione
re.I Questo modificatore ignorerà il caso delle stringhe e dei pattern durante l’abbinamento.
re.L Questo modificatore è usato per interpretare le parole rispetto al locale corrente.
re.M Questo modificatore è usato per fare $ per abbinare alla fine della riga e non alla fine della stringa. Allo stesso modo, ^ corrisponderà all’inizio della riga invece che all’inizio della stringa.
re.S Questo modificatore è usato per fare un punto . per corrispondere a qualsiasi carattere. Questo include anche una nuova riga.
re.U Questo modificatore è usato per interpretare i caratteri come set di caratteri Unicode.
re.X Si usa per ignorare gli spazi bianchi. Farà # come marcatore di commento.

Utilizzo di più valori di flag

Considerate il seguente codice Python in cui vedrete come usare più valori di flag per cambiare il comportamento di RE. I valori dei flag multipli possono essere inclusi dall’operatore bitwise OR (|):

import re

s = re.search("L", "Hello")
print(s)  # Output: None, L is there but in small letter and we didn't use flags

s = re.search("L", "Hello", re.I)
print(s)  # Output: 1

s = re.search("L", "^Hello", re.I | re.M)
print(s)  # Output: 1, searching will be made from the start of line and case is ignored

Controllo dei caratteri ammessi

È anche possibile controllare se una certa stringa contiene o meno una particolare gamma di caratteri.

Definizione di una funzione e controllo dei caratteri ammessi

Si consideri il seguente esempio in cui viene definita una funzione e viene utilizzato anche uno schema precompilato per controllare se i certi caratteri sono o meno nella stringa passata:

import re


def check(str):
    s = re.compile(r"[^A-Z]")
    str = s.search(str)
    return not bool(str)


print(check("HELLOPYTHON"))  # Output: True
print(check("hellopython"))  # Output: False

In questa funzione, uno schema che è r '[^A-Z]' viene compilato e usato per cercare in una stringa passata quando viene chiamata questa funzione chiamata check. Questa funzione controlla effettivamente se la stringa passata contiene le lettere A-Z (maiuscole) o no. Allo stesso modo, si può vedere che quando si passa una stringa in lettere minuscole false viene restituita.

Cerca e sostituisci

Il modulo re fornisce una funzione che è la funzione sub che viene usata per sostituire tutte le occorrenze del pattern nella string data usando l’attributo repl nella funzione. I caratteri saranno sostituiti fino al raggiungimento del numero di count. La funzione sub restituirà la stringa aggiornata.

La seguente è la sintassi della sotto funzione:

re.sub(pattern, repl, string, count=0)

Usando la funzione sub

Si consideri l’esempio seguente in cui la funzione sub sostituisce l’intera stringa con una data stringa:

import re

s = "Playing 4 hours a day"
obj = re.sub(r"^.*$", "Working", s)
print(obj)
Working

Qui si usa la funzione sub. Lo schema r'^.*$ significa partire dall’inizio della stringa e poi .* significa qualsiasi cosa sia nella stringa fino alla fine $ della stringa. Poi l’argomento "Working" sostituirà l’intera stringa s.

Usare la funzione sub per cancellare tutte le cifre di una stringa

Si consideri il seguente esempio in cui la funzione sub elimina le cifre nella stringa data. A questo scopo potete usare \d:

import re

s = "768 Working 2343 789 five 234 656 hours 324 4646 a 345 day"
obj = re.sub(r"\d", "", s)
print(obj)
Working   five   hours   a  day

Allo stesso modo, è possibile cancellare i caratteri dalla stringa. A questo scopo potete usare \D.

import re

s = "768 Working 2343 789 five 234 656 hours 324 4646 a 345 day"
obj = re.sub(r"\D", "", s)
print(obj)
76823437892346563244646345

La funzione findall()

La funzione findall restituisce una lista di tutte le stringhe che corrispondono allo schema. La differenza tra la funzione search e findall è che findall trova tutte le corrispondenze, mentre search trova solo la prima corrispondenza. Questa funzione trova le corrispondenze non sovrapposte e le restituisce come una lista di stringhe.

La seguente è la sintassi della funzione findall:

findall(pattern, string, flags)

Qui pattern è il pattern RE che troverete in una data string con alcuni valori flags per esempio re.I per ignorare il caso.

Trovare tutte le corrispondenze non sovrapposte

Nell’esempio seguente, findall trova corrispondenze non sovrapposte:

import re

str = "Working 6 hours a day. Studying 4 hours a day."
mobj = re.findall(r"[0-9]", str)
print(mobj)
["6", "4"]

r'[0-9]' è un modello che trova tutte le cifre nella stringa data e viene restituito una lista di stringhe (indipendentemente dal fatto che siano cifre) che è memorizzato in mobj.

findall con i file

È anche possibile utilizzare findall per trovare in un file. Quando si usa findall con un file, esso restituisce una lista di tutte le stringhe corrispondenti nel file. Come read() funzione di file verrà utilizzata in modo da non dover iterare attraverso ogni riga del file usando un loop, poiché restituisce l’intero testo del file come una stringa. Considerate il seguente esempio:

import re

file = open("asd.txt", "r")
mobj = re.findall(r"arg.", file.read())
print(mobj)
file.close()
["arg,", "arg,", "arg,", "argv", "argv", "argv"]

In questo esempio, il file viene aperto per primo in modalità lettura. Lo schema r'arg.' è abbinato al contenuto del file e si ha la lista delle stringhe corrispondenti nell’output.

La funzione finditer()

La funzione finditer può essere usata per trovare il pattern RE nelle stringhe insieme alla posizione delle stringhe corrispondenti che è l’indice delle stringhe. Questa funzione in realtà itera attraverso le stringhe corrispondenti e restituisce gli indici o le posizioni della stringa.

La seguente è la sintassi della funzione finditer:

finditer(pattern, string, flags)

Iterare sulle corrispondenze

L’unica differenza tra findall e finditer è che finditer restituisce anche l’indice insieme alle stringhe corrispondenti. Nel codice sottostante, finditer è usato per trovare le posizioni delle stringhe corrispondenti mentre si itera sulle corrispondenze (stringhe corrispondenti) usando per il loop.

import re

str = "Working 6 hours a day. Studying 4 hours a day."
pat = r"[0-9]"
for mobj in re.finditer(pat, str):
    s = mobj.start()
    e = mobj.end()
    g = mobj.group()
    print("{} found at location [{},{}]".format(g, s, e))
6 found at location [8,9]
4 found at location [32,33]

In questo esempio, lo schema è costituito dalle cifre da 0 a 9 che si trovano in str. for loop itera sulle stringhe corrispondenti restituite da finditer. Nel loop, le funzioni start, end e group restituiscono rispettivamente l’indice iniziale, l’indice finale e la corrispondenza trovata in ogni iterazione della stringa restituita da finditer.

La funzione split()

La funzione split è usata per dividere una stringa.

La seguente è la sintassi della funzione split:

split(patter, string, maxsplit, flags)

Qui max è il numero totale di split di stringhe. Se si verificano al massimo split maxsplit, il resto della stringa viene restituito come elemento finale della lista. Il valore predefinito di max è 0 che significa split illimitati.

Dividere una stringa

La funzione split restituisce ogni parola in una stringa

Nel codice sottostante, una stringa viene suddivisa secondo lo schema dato e il numero massimo di suddivisioni.

import re

str = "Birds fly high in the sky for ever"
mobj = re.split("\s+", str, 5)
print(mobj)
["Birds", "fly", "high", "in", "the", "sky for ever"]

In questo esempio, il carattere del pattern \s è un carattere speciale che corrisponde al carattere dello spazio bianco, che equivale a [ \t\n\r\f\v]. Quindi si potrebbero avere parole separate. Il valore di max è qui 5 che fa 6 split, e l’ultimo elemento è il resto della stringa dopo il 5° split.

Gli schemi di base di re

Le espressioni regolari possono specificare modelli che vengono confrontati con determinate stringhe. Di seguito sono riportati i Pattern di base delle espressioni regolari:

Modello Descrizione
^ Si usa per abbinare all’inizio della stringa.
$ Questo schema corrisponderà alla fine della stringa.
. Il punto è usato per far corrispondere un carattere (la newline non è inclusa).
[...] Si usa per far corrispondere un singolo carattere tra parentesi.
[^...] Questo corrisponderà ad un singolo carattere ma non tra parentesi.
* 0 o più occorrenze di re precedenti in una data stringa.
+ 1 o più occorrenze di re precedenti in una data stringa.
? 0 o 1 occorrenze di re precedenti in una data stringa.
{n} Corrisponderà a n numero di occorrenze in una determinata stringa.
{n,} Corrisponderà a n o più di n numero di occorrenze.
{n,m} Questo schema viene utilizzato per abbinare almeno n e al massimo m nella stringa.
`a b`
(ri) Questo schema viene utilizzato per raggruppare le espressioni regolari e ricorda il testo abbinato.
(?imx) Si attiva temporaneamente su i o m o x in RE. Quando si usa la parentesi, allora è interessata solo l’area della parentesi.
(?-imx) Si disattiverà temporaneamente i o m o x in RE. Quando si usa la parentesi, allora è interessata solo l’area della parentesi.
(?:re) Questo schema viene utilizzato per raggruppare le espressioni regolari, ma non ricorda il testo abbinato.
(?imx: re) Si alternerà temporaneamente su i o m o x in RE all’interno di una parentesi.
(?-imx: re) Si disattiverà temporaneamente i o m o x in RE all’interno di una parentesi.
(?#...) È un commento.
(?= re) Viene utilizzato per specificare la posizione utilizzando uno schema. Non ha alcun intervallo.
(?! re) Si usa per specificare la posizione utilizzando una negazione del modello. Non ha alcun intervallo.
(?> re) Questo modello viene utilizzato per abbinare un modello indipendente.
\w Questo schema viene utilizzato per abbinare le parole.
\W Questo schema viene utilizzato per abbinare le parole non scritte.
\s Si abbinerà ai bianchi. \x22e’ uguale a [ \x22n \x22f \x22.]
\S Si abbinerà a spazi non bianchi.
\d pari a [0-9]. Corrisponde alle cifre della stringa.
\D Corrisponde a non cifre.
\A corrispondono all’inizio della stringa.
\Z corrisponde all’estremità della stringa. E se c’è una newline, questa corrisponderà prima della newline.
\G fino al punto in cui è stata terminata l’ultima partita.
\b corrisponde ai confini delle parole quando è al di fuori delle parentesi, ma quando è all’interno delle parentesi corrisponde al backspace.
\B corrispondono ai confini delle non parole.
n, \x22t\x22, \x22t\x22, ecc.\x22 \n è usato per far corrispondere le nuove linee, \t corrisponderà alla scheda e così via.
\1...\9 Questo schema corrisponderà all’ennesima sottoespressione (raggruppata).
\10 \10 di solito corrisponde all’ennesima sottoespressione (raggruppati) se la partita è già fatta. Se la partita non è già fatto \10 fornirà la rappresentazione ottale di un codice di caratteri.

Casi di ripetizione

La tabella seguente mostra alcuni esempi di casi di ripetizione con descrizione:

Esempi Descrizioni
ab? Corrisponderà o a o ab.
ab* ab* corrisponderà alle ab e alle a e a qualsiasi a seguito di qualsiasi b.
ab+ ab+ significa a’s seguito da b e non solo a. a deve essere seguito da non zero b.
\d{2} Corrisponderà esattamente a 2 cifre.
\d{2,} Corrisponderà a 2 o più cifre.
\d{2,4} Corrisponderà alle cifre 2, 3 e 4.

Ripetizione Nongreedy

Nelle espressioni regolari, la ripetizione è per default avida che cerca di abbinare il maggior numero possibile di ripetizioni.

I qualificatori come *, + e ? sono qualificatori avidi. Quando si usa .*, si esegue una corrispondenza avida e corrisponde all’intera stringa con il risultato di far corrispondere il maggior numero possibile di caratteri. Considerate il codice qui sotto:

import re

mobj = re.match(r".*", "Birds fly high in sky")
print(mobj.group())
Birds fly high in the sky

Così potete vedere qui che l’intera stringa è abbinata.

Quando si aggiunge ? con .+ si avrà un re non avido e il pattern .+? corrisponderà al minor numero possibile di caratteri nella stringa.

import re

mobj = re.match(r".*", "Birds fly high in sky")
print(mobj.group())

Il risultato è il primo carattere della stringa

B

Caratteri speciali e sequenze in re

I caratteri speciali in re iniziano con un \. Ad esempio, abbiamo \A che corrisponderà dall’inizio della stringa.

Questi caratteri speciali sono descritti nella tabella qui sopra.

In questa sezione, vi verranno mostrati gli esempi di alcuni dei caratteri speciali:

import re

str = "Birds fly high in the sky"
# \A
# OUTPUT: B, here \A will match at beginning only.
mobj = re.match(r"\Ab", str, re.I)

# \d
mobj = re.match(r"\d", "4 birds are flying")  # OUTPUT: 4

# \s
mobj = re.split("\s+", "birds fly high in the sky", 1)  # OUTPUT: ['Birds', 'fly']

La funzione escape

La funzione escape è usata per sfuggire a tutti i caratteri della stringa. Le lettere ASCII, i numeri e _ non saranno sfuggiti. La funzione escape è usata quando si vogliono estrarre metacaratteri da una stringa.

Di seguito è riportata la sintassi della funzione di escape:

escape(pattern)

Nell’esempio seguente, una stringa www.python.org viene passata alla funzione di escape. In questo abbiamo . che è un metacarattere e verrà estratta o abbinata:

print(re.escape("www.python.org"))
www\.python\.org

Qui . è un metacarattere che viene estratto o abbinato. Ogni volta che un metacarattere viene abbinato usando la funzione di escape si avrà \ prima del carattere.

Caratteri speciali di fuga

I caratteri come parentesi tonde [ e ] non possono essere abbinati. Considerate il seguente esempio:

import re

mobj = re.search(r"[a]", "[a]b")
print(mobj.group())
a

Qui si può vedere che le parentesi [ e ] non sono abbinate.

Potete abbinarle utilizzando la funzione di escape:

import re

mobj = re.search(r"\[a\]", "[a]b")
print(mobj.group())
[a]b

La funzione group()

La funzione group è usata per restituire uno o più sottogruppi della partita trovata. La funzione group può avere alcuni argomenti.

La seguente è la sintassi della funzione di gruppo:

group(group1, group2, ..., groupN)

Se si ha un singolo argomento nella funzione di gruppo, il risultato sarà una singola stringa, ma quando si ha più di un argomento, allora il risultato sarà una tupla (contenente un elemento per argomento).

Quando non c’è un argomento, per default l’argomento sarà zero e restituirà l’intera partita.

Quando l’argomento groupN è zero, il valore restituito sarà l’intera stringa corrispondente.

Quando si specifica il numero di gruppo o l’argomento come valore negativo o come valore maggiore del numero di gruppi nel pattern, allora si verificherà l’eccezione IndexError.

Considerate il codice sottostante in cui non c’è un argomento nella funzione group che è equivalente al group(0).

import re

str = "Working 6 hours a day"
mobj = re.match(r"^.*", str)
print(mobj.group())
Working 6 hours a day

Qui si usa group() e si ha l’intera stringa abbinata.

Scegliere parti di testi corrispondenti

Nell’esempio seguente, la funzione group viene utilizzata con argomenti per raccogliere i gruppi corrispondenti:

import re

a = re.compile("(p(q)r)s")
b = a.match("pqrs")
print(b.group(0))
print(b.group(1))
print(b.group(2))
pqrs
pqr
q

Qui group(0) restituisce l’intera partita. Il group(1) restituisce la prima partita che è pqr e il group(2) restituisce la seconda partita che è q.

Gruppi nominati

Utilizzando i gruppi con nome è possibile creare un gruppo di cattura. Questo gruppo può essere riferito al nome. Considerate l’esempio seguente:

import re

mobj = re.search(r"Hi (?P<name>\w+)", "Hi Roger")
print(mobj.group("name"))
Roger

Gruppi non catturati

Il gruppo non captante può essere creato usando ?:. Il gruppo non-capturing viene utilizzato quando non si desidera il contenuto del gruppo.

import re

mobj = re.match("(?:[pqr])+", "pqr")
print(mobj.groups())
()
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook