La ricerca di documenti secondo specifici caratteri o stringhe di caratteri concrete in campo in­for­ma­ti­co figura da sempre nelle attività standard che vanno sempre sbrigate. Spesso l'o­biet­ti­vo consiste nel mo­di­fi­ca­re o so­sti­tui­re le sezioni di testo o le righe di codice cercate, un compito che si rivela tanto più complesso quante sono le volte in cui le spe­ci­fi­che stringhe di caratteri appaiono nel documento. La scoperta di una soluzione che influenza tutt'oggi lo sviluppo di software e che sem­pli­fi­ca con­si­de­re­vol­men­te tali attività ri­pe­ti­ti­ve sotto forma delle co­sid­det­te espres­sio­ni regolari (ingl. regular ex­pres­sions) risale già agli anni '50.

Che cos'è un'e­spres­sio­ne regolare?

Le espres­sio­ni regolari (ingl. regular ex­pres­sions) sono unità de­scrit­ti­ve di linguaggi regolari che ap­par­ten­go­no ai co­sid­det­ti linguaggi in­for­ma­ti­ci. Sono uno strumento centrale dell'in­for­ma­ti­ca teorica che, tra l'altro, co­sti­tui­sce la base per lo sviluppo e l'e­se­cu­zio­ne di programmi in­for­ma­ti­ci e per la co­stru­zio­ne dei com­pi­la­to­ri necessari a tale scopo. Ecco perché le espres­sio­ni regolari, spesso definite anche regex e basate su regole sin­tat­ti­che ben definite, vengono applicate in par­ti­co­la­re nel­l'at­ti­vi­tà di sviluppo di software.

Per ogni espres­sio­ne regolare esiste un automa a stati finiti (noto anche come macchina a stati finiti) che accetta il lin­guag­gio spe­ci­fi­ca­to dal­l'e­spres­sio­ne e che può essere svi­lup­pa­to da un'e­spres­sio­ne regolare ri­cor­ren­do all'algoritmo di Thompson. D’altro canto per ogni automa a stati finiti esiste anche un'e­spres­sio­ne regolare in grado di de­scri­ve­re il lin­guag­gio accettato dal­l'au­to­ma e che può essere generata a scelta at­tra­ver­so l'Algoritmo di Kleene o l'eli­mi­na­zio­ne di Gauss.

N.B.

Un automa è un modello di com­por­ta­men­to che si compone di stati, passaggi di stato e azioni. Viene definito a stati finiti, se la quantità di stati che può accettare è finita (ossia limitata).

Un esempio noto dell'uso di espres­sio­ni regolari in ambito in­for­ma­ti­co è co­sti­tui­to dalla funzione Trova/So­sti­tui­sci degli editor di testo, im­ple­men­ta­ta per la prima volta negli anni '60 da Ken Thompson, pioniere in­for­ma­ti­co e svi­lup­pa­to­re dei sistemi operativi UNIX, nel­l'e­di­tor di testo orientato alla linea QED e nel suo suc­ces­so­re ed. Questa funzione consente di cercare de­ter­mi­na­te stringhe di caratteri nei testi e, se lo si desidera, di so­sti­tuir­le mediante un'altra stringa qualsiasi,

De­fi­ni­zio­ne: Espres­sio­ni Regolari (regex)

Espres­sio­ni regolari (ingl. regular ex­pres­sions): le espres­sio­ni regolari sono stringhe di caratteri basate su regole sin­tat­ti­che che con­sen­to­no di de­scri­ve­re le stringhe di caratteri. Come tali, esse sono parte in­te­gran­te dei linguaggi regolari, un sot­to­grup­po dei linguaggi formali che svolge un ruolo di grande im­por­tan­za, in par­ti­co­la­re in campo in­for­ma­ti­co e so­prat­tut­to nello sviluppo di software.

Come funziona un'e­spres­sio­ne regolare?

È possibile costruire un'e­spres­sio­ne regolare esclu­si­va­men­te mediante caratteri normali (ad es. abc) oppure tramite una com­bi­na­zio­ne di caratteri normali e me­ta­ca­rat­te­ri (ad es. ab*c). In questo contesto, i me­ta­ca­rat­te­ri hanno il compito di de­scri­ve­re de­ter­mi­na­te co­stru­zio­ni o ordini di caratteri, anche se un carattere deve trovarsi ad esempio al­l'i­ni­zio della riga o se un carattere può o deve comparire esat­ta­men­te una volta, più volte o con minore frequenza. Di seguito ri­por­tia­mo uno dei due esempi di espres­sio­ni regolari pre­ce­den­ti:

abc: questo semplice modello di regex abc richiede una con­cor­dan­za esatta. Vengono quindi ricercate stringhe di caratteri, in cui non solo sono contenuti tutti i caratteri "abc", ma nelle quali essi compaiono anche nella sequenza esatta, come nella frase: "Conosci l'abc?".

ab*c: al contrario, le espres­sio­ni regolari con caratteri speciali fun­zio­na­no in modo leg­ger­men­te diverso, poiché non solo vengono ricercate con­cor­dan­ze esatte, ma anche scenari speciali. In questo caso, il simbolo asterisco provvede affinché vengano ricercate stringhe di caratteri che iniziano con la lettera "a" e che terminano con la lettera "c". Tra queste due lettere può essere presente un numero qualsiasi di lettere "b"; in questo modo si trova una con­cor­dan­za in "abc", ma anche in "abbbbc" e "cbbabbcba".

Inoltre, ciascuna regex può essere associata a un'azione concreta quale, ad esempio, la funzione "So­sti­tui­sci" citata in pre­ce­den­za. Questa azione viene sempre eseguita dove ci si attiene alla ri­spet­ti­va espres­sio­ne regolare, ossia dove si ha una con­cor­dan­za cor­ri­spon­den­te come negli esempi descritti.

Quali sfide sono associate al­l'im­pie­go di espres­sio­ni regolari?

Chi desidera lavorare con le istru­zio­ni di regex ha diverse libertà, poiché per ogni im­po­sta­zio­ne del problema che si desidera risolvere con un'e­spres­sio­ne regolare sono sempre presenti più soluzioni. Tuttavia, il fatto che sia possibile ottenere il risultato de­si­de­ra­to in diversi modi non sempre co­sti­tui­sce un vantaggio:

ad esempio, le istru­zio­ni possono essere molto generiche per rag­giun­ge­re l'o­biet­ti­vo de­si­de­ra­to in qualsiasi caso. Tuttavia, se de­si­de­ra­te ottenere un risultato il più possibile accurato, non potete evitare di formulare un modello di regex specifico. Inoltre, è con­si­glia­bi­le con­si­de­ra­re la lunghezza in generale: più compatta è un'e­spres­sio­ne regolare, minore sarà la sua durata di ela­bo­ra­zio­ne. Tuttavia, in questo caso non dovete perdere di vista la leg­gi­bi­li­tà. Infatti, la possibile modifica futura delle espres­sio­ni regolari uti­liz­za­te co­sti­tui­rà un ostacolo con­si­de­re­vo­le se le istru­zio­ni ori­gi­na­rie sono troppo com­pli­ca­te e non com­men­ta­te.

In generale, nella creazione delle espres­sio­ni regolari occorre de­ter­mi­na­re il rapporto ottimale tra com­pat­tez­za e spe­ci­fi­ci­tà.

Quali regole sin­tat­ti­che si applicano alle espres­sio­ni regolari?

Come già men­zio­na­to, è possibile uti­liz­za­re le espres­sio­ni regolari in diversi linguaggi quali, ad esempio, Perl, Python, Ruby, Ja­va­Script, XML o HTML, mentre l'u­ti­liz­zo o la funzione possono essere molto diversi. Ad esempio, nel lin­guag­gio Ja­va­Script vengono impiegati i motivi di regex con i metodi String search(), match() o replace(), mentre le espres­sio­ni nei documenti XML servono a limitare i contenuti di elementi. Tuttavia, per quanto riguarda la sintassi non vi sono dif­fe­ren­ze tra i singoli linguaggi di pro­gram­ma­zio­ne e di mark up nel caso delle espres­sio­ni regolari.

Un'e­spres­sio­ne regolare può quindi comporsi di due o tre parti, in­di­pen­den­te­men­te dal lin­guag­gio in cui essa viene uti­liz­za­ta:

Pattern (motivo di ricerca) L'e­le­men­to centrale è il pattern, ossia il motivo di ricerca generale. Come il­lu­stra­to nella sezione pre­ce­den­te, esso può comporsi esclu­si­va­men­te di caratteri semplici o di una com­bi­na­zio­ne di caratteri semplici e di caratteri speciali.
Delimiter (De­li­mi­ta­to­re) I delimiter de­fi­ni­sco­no l'inizio e la fine del pattern. In linea di massima, vengono presi in con­si­de­ra­zio­ne tutti i caratteri non al­fa­nu­me­ri­ci (ad eccezione della barra ro­ve­scia­ta). Ad esempio, PHP prevede come de­li­mi­ta­to­ri hashtag (#pattern#), simboli di per­cen­tua­le (%pattern%), di addizione (+pattern+) o tilde (~pattern~). Tuttavia, nella maggior parte dei linguaggi vengono at­tual­men­te impiegati vir­go­let­te ("pattern") o barre (/pattern/).
Modifier (Mo­di­fi­ca­to­re) I modifier possono essere aggiunti a un motivo di ricerca per mo­di­fi­ca­re l'e­spres­sio­ne regolare. Ad esempio, il mo­di­fi­ca­to­re i ha la funzione di rimuove la di­stin­zio­ne tra lettere maiuscole e minuscole. Questo garantirà l'im­por­tan­za delle lettere maiuscole e minuscole e la loro validità per tutte le espres­sio­ni regolari.

Tra i tipici caratteri speciali sin­tat­ti­ci, che possono ampliare i pattern con de­ter­mi­na­te opzioni, troviamo i seguenti:

Caratteri speciali di regex sin­tat­ti­che Funzione
[] Un paio di parentesi quadre indica una classe di caratteri che si trova sempre in un motivo di ricerca per un singolo carattere.
() Un paio di parentesi tonde indica una classe di caratteri composta da uno o più caratteri, che possono essere connessi tra loro.
- Funge da in­di­ca­zio­ne del range (da [… ] a […]), se si trova tra due caratteri normali
^ Limita la ricerca al­l'i­ni­zio di una riga (ulteriore funzione: simbolo di sot­tra­zio­ne in classi di caratteri)
$ Limita la ricerca alla fine di una riga (ulteriore funzione
. Viene impiegato per qualsiasi carattere
* Il numero di caratteri, della classe o del gruppo che compare davanti a un asterisco può essere un numero qualsiasi (zero incluso).
+ Il carattere, la classe o il gruppo che compare davanti a un segno di addizione deve essere presente almeno una volta.
? Il carattere, la classe o il gruppo che compare davanti a un punto in­ter­ro­ga­ti­vo è opzionale e può comparire al massimo una volta.
{n} Il carattere, la classe o il gruppo pre­ce­den­te compare esat­ta­men­te n volte.
{n,m} Il carattere, la classe o il gruppo pre­ce­den­te compare esat­ta­men­te almeno n volte e al massimo m volte.
{n,} Il carattere, la classe o il gruppo pre­ce­den­te compare come minimo n volte o con maggiore frequenza.
\b Indica di tener conto del limite di parole durante la ricerca.
\B Indica di ignorare il limite di parole durante la ricerca.
\d Qualsiasi cifra; ab­bre­via­zio­ne per la classe di caratteri [0-9]
\D Qualsiasi non cifra; ab­bre­via­zio­ne per la classe di caratteri [^0-9]
\w Qualsiasi carattere al­fa­nu­me­ri­co; ab­bre­via­zio­ne per la classe di caratteri [a-zA-Z_0-9]
\W Qualsiasi carattere non al­fa­nu­me­ri­co; ab­bre­via­zio­ne per la classe di caratteri [^\w]

Tutorial: spie­ga­zio­ne delle possibili espres­sio­ni regolari ri­cor­ren­do ad esempi

Mentre nelle sezioni pre­ce­den­ti di questo articolo sono stati riassunti i principi delle regex, il prossimo tutorial si ripropone di il­lu­stra­re il fun­zio­na­men­to delle stringhe di caratteri pratiche. In esso vengono il­lu­stra­te le diverse pos­si­bi­li­tà e i trucchi sin­tat­ti­ci con esempi concreti di espres­sio­ni regolari, nonché di espres­sio­ni semplici e complesse.

Espres­sio­ni regolari composte da un elemento

La forma più semplice di regex è co­sti­tui­ta da un motivo di ricerca che prevede come risultato un unico elemento. Purché non ri­cer­chia­te un elemento concreto, è possibile definire senza problemi una simile espres­sio­ne regolare composta da un elemento ser­ven­do­si di una classe di caratteri. La seguente espres­sio­ne accetta, a scelta, le cifre "1", "2", "3", "4", "5", "6" o "7" come possibile risultato:

[1234567]

Dato che in questo caso i numeri si sus­se­guo­no di­ret­ta­men­te, sarebbe possibile anche la seguente forma sem­pli­fi­ca­ta:

[1-7]

Al contrario, se occorre mo­di­fi­ca­re l'e­spres­sio­ne regolare, ri­muo­ven­do la cifra "4" dalla ricerca, potete uti­liz­za­re anche la variante sem­pli­fi­ca­ta con il segno di sot­tra­zio­ne:

[1-35-7]
N.B.

I singoli caratteri di un pattern di regex non sono separati da spazi vuoti.

Espres­sio­ni regolari composte da più elementi

Potete lavorare con classi di caratteri anche nel caso di un'e­spres­sio­ne regolare composta da più elementi per rendere possibile la selezione di diversi risultati. Ad esempio, se l'e­spres­sio­ne rileva due elementi per i quali sono con­ce­pi­bi­li diversi risultati, dovrete sem­pli­ce­men­te allineare due classi di caratteri una dopo l'altra:

[1-7][a-c]

Al primo elemento, un numero compreso tra "1" e "7", seguirà anche una delle lettere "a", una "b" o una "c". Come già men­zio­na­to, in questo caso è ob­bli­ga­to­rio ricorrere alle lettere minuscole. Tuttavia, prima di trattare i mo­di­fi­ca­to­ri, potete già integrare lettere maiuscole ap­por­tan­do una piccola modifica, come il­lu­stra­to di seguito:

[1-7][a-cA-C]

Espres­sio­ni regolari con elementi opzionali

In­di­pen­den­te­men­te dal fatto che siate alla ricerca di più elementi al­l'in­ter­no di una singola espres­sio­ne regolare o che ef­fet­tuia­te la ricerca ser­ven­do­vi di più gruppi di caratteri, è possibile che de­ter­mi­na­ti elementi debbano o possano essere contenuti solo in de­ter­mi­na­te con­di­zio­ni. Questo potrebbe accadere, ad esempio, con un'e­spres­sio­ne regolare che deve filtrare tutti i numeri civici. In questo caso, i numeri civici co­sti­tui­ti da un'unica cifra si con­fron­ta­no talvolta con numeri di due o persino di tre cifre. Inoltre, vi sono indirizzi nei quali una lettera viene applicata al numero civico come elemento ag­giun­ti­vo. È possibile includere questa forma aggregata in com­bi­na­zio­ni possibili mediante le seguenti istru­zio­ni di regex:

[1-9][0-9]?[0-9]?[a-z]?

L'unico elemento ob­bli­ga­to­rio di questo motivo di ricerca è un numero compreso tra "1" e "9". In opzione, possono seguire due cifre comprese tra "0" e "9" e una lettera. I caratteri opzionali vengono segnalati dal punto in­ter­ro­ga­ti­vo che li segue nel codice.

Mentre la co­stru­zio­ne per i numeri a tre cifre più lettera ag­giun­ti­va è chiara, questa sarebbe con­si­de­re­vol­men­te diversa con numeri fino a dieci cifre. In questo caso è con­si­glia­bi­le impiegare le parentesi graffe, come nel seguente esempio di espres­sio­ni regolari:

[1-9][0-9]{0,9}

Come il­lu­stra­to nel­l'e­sem­pio pre­ce­den­te, è in­nan­zi­tut­to richiesto un numero tra "1" e "9". Tuttavia, si può decidere se non far seguire alcuna cifra o se far seguire cifre fino a nove, ossia comprese tra "0" e "9", affinché il risultato della ricerca possa essere co­sti­tui­to da un massimo di dieci cifre.

Espres­sio­ni regolari con ri­pe­ti­zio­ni con una frequenza a piacere

Negli esempi finora addotti di espres­sio­ni composte da un elemento o e da più elementi era noto sia il numero minimo che il numero massimo di caratteri. Tuttavia, esistono scenari in cui la quantità di caratteri di una regex non deve essere definita esat­ta­men­te in anticipo. I parametri necessari sono quindi l'a­ste­ri­sco e il segno di addizione, che con­sen­to­no il ricorso a qualsiasi ri­pe­ti­zio­ne di un carattere o di una classe o gruppo di caratteri. Ad esempio, ciò consente di rea­liz­za­re tutte le stringhe di caratteri con un numero qualsiasi di cifre (anche lo "zero") con la seguente espres­sio­ne regolare:

[0-9]*

La stessa regola si applica anche quando viene ricercata una com­bi­na­zio­ne di caratteri concreta, nella quale possono comparire uno (o più) caratteri tutte le volte che lo si desidera, come nel­l'e­sem­pio seguente:

ab*

In questo caso, tra i possibili risultati rientrano sia la parola "avere" che "abete" e "abbasstanza". Tuttavia, se si dovesse escludere il primo risultato o se il carattere spe­ci­fi­ca­to dovesse comparire almeno una volta, si dovrà uti­liz­za­re il segno di addizione:

ab+

Negare classi di caratteri

Se volete impiegare espres­sio­ni regolari con classi di caratteri che di norma rap­pre­sen­ta­no uno o più caratteri qualsiasi, ma che in questo caso escludono come risultato uno o più caratteri specifici, avrete bisogno del carattere di negazione "^". Questo carattere si trova sempre al­l'in­ter­no delle parentesi di una classe di caratteri ed è valido solo al­l'in­ter­no di queste parantesi. La seguente istru­zio­ne offre un ottimo esempio di una classe di caratteri negata:

C[^a]sa

Per quanto riguarda il secondo carattere, esso può essere co­sti­tui­to da un carattere qualsiasi eccetto "a", per cui la parola "cosa" offre le con­cor­dan­ze richieste. Al contrario, la parola "casa" non offre tali con­di­zio­ni perché non si attiene neanche al­l'e­spres­sio­ne regolare.

Caratteri jolly

Le espres­sio­ni regolari con­sen­to­no di lavorare anche con caratteri jolly, che a scelta rap­pre­sen­ta­no uno, più o nessun carattere (a seconda del me­ta­ca­rat­te­re impiegato) al­l'in­ter­no di un motivo di ricerca. Il carattere jolly viene generato mediante un punto, che com­bi­ne­re­te con i caratteri speciali elencati pre­ce­den­te­men­te per le ri­pe­ti­zio­ni, se de­si­de­ra­te risultati diversi da caratteri singoli. Simili espres­sio­ni regolari con­sen­to­no, ad esempio, di ricercare al­l'in­ter­no di una banca dati una persona della quale conoscete il nome e cognome, ma di cui non sapete se sia re­gi­stra­ta con un secondo nome:

Paolo .*Rossi

In questo caso, tra i possibili risultati rientrano sia "Paolo Luca Rossi" (e qualsiasi altra com­bi­na­zio­ne con doppio nome) o "Paolo L. Rossi" nonché "Paolo Rossi". Se si devono con­si­de­ra­re esclu­si­va­men­te le varianti con un secondo nome, invece del­l'a­ste­ri­sco dovrete uti­liz­za­re un segno di addizione:

Paolo .+Rossi

Un ottimo esempio del­l'im­pie­go efficace di un carattere jolly per un carattere singolo è il seguente motivo di ricerca, con­cor­dan­te sia con "Dire" che con "Dare“:

D.re

Al­ter­na­ti­ve

Potete formulare espres­sio­ni regolari, affinché vi siano due o più al­ter­na­ti­ve per una con­cor­dan­za. In questo caso le al­ter­na­ti­ve vengono separate da un trattino verticale, come nel­l'e­sem­pio seguente:

Fiore|Flora

Pertanto, sia "Fiore" che "Flora" offrono una con­cor­dan­za.

È possibile formulare al­ter­na­ti­ve anche all'interno di parole o di stringhe di caratteri facendo ricorso a gruppi:

(Lune|Marte|Giove|Vener|)dì|Sabato

In questo esempio, ciascun giorno della settimana co­sti­tui­sce un risultato po­ten­zia­le, poiché tutti i nomi dei giorni della settimana che terminano in "dì", e che sono proposti come al­ter­na­ti­va, vengono cor­ret­ta­men­te rilevati anche nella forma ab­bre­via­ta grazie al rag­grup­pa­men­to in parentesi tonde.

Gruppi

I gruppi di caratteri, come quelli il­lu­stra­ti nel­l'e­sem­pio della sezione pre­ce­den­te, rientrano negli elementi strut­tu­ra­li delle espres­sio­ni regolari in qualità di classi di caratteri. Possono essere definiti da un paio di parentesi tonde e, di norma, rap­pre­sen­ta­no un pattern co­sti­tui­to da uno o più caratteri. Ciascuna regex è in sostanza un gruppo, con il quale la de­fi­ni­zio­ne tramite parentesi non è ap­pli­ca­bi­le. Al­l'in­ter­no delle espres­sio­ni, i gruppi concedono la pos­si­bi­li­tà di impiegare operatori, quali segni di se­pa­ra­zio­ne o di ri­pe­ti­zio­ne (più e asterisco), in un'e­spres­sio­ne parziale de­si­de­ra­ta:

ab(cd)+

In questo caso, la ri­pe­ti­zio­ne de­si­de­ra­ta è ap­pli­ca­bi­le per il gruppo di caratteri "cd", mentre sarebbe ap­pli­ca­bi­le solo per la "d" se fosse formulata allo stesso modo ma senza ricorrere alle parentesi. Al­l'in­ter­no di una regex non vi sono limiti relativi alla quantità dei gruppi contenuti.

An­ni­da­men­ti

Al­l'in­ter­no di un'e­spres­sio­ne regolare non solo può esservi un numero di gruppi qualsiasi, ma possono essere annidati tra loro tutti i gruppi che si desidera per formulare relazioni complesse tra caratteri semplici e speciali anche senza lunghe stringe di caratteri inutili. Un esempio di ciò è co­sti­tui­to dal seguente motivo di regex che ha come possibili risultati quattro modelli di auto "VW Golf", "VW Polo", "Fiat Punto" o "Fiat Panda":

(VW (Golf|Polo)|Fiat (Punto|Panda))

Limiti di parola

Se nell'uso di un'e­spres­sio­ne regolare si deve tener conto dei limiti di parola, ossia dell'inizio o della fine di una sequenza al­fa­nu­me­ri­ca, occorre spe­ci­fi­car­li ri­cor­ren­do ai me­ta­ca­rat­te­ri. A tal fine, molti linguaggi uti­liz­za­no la com­bi­na­zio­ne "\b", che può essere premessa, aggiunta o premessa e aggiunta.

La prima variante impone che la sequenza di ricerca si trovi al­l'i­ni­zio della parola:

\bun

Una con­cor­dan­za per questa espres­sio­ne regolare è offerta, ad esempio, dalla parola"uno". Al contrario, la parola "Alcuno" è esclusa dai possibili risultati, poiché le lettere "Alc" procedono il carattere oggetto della ricerca. Per ribaltare la si­tua­zio­ne, uti­liz­za­te la variante numero due e ag­giun­ge­te il carattere speciale:

un\b

Infine, con la terza opzione fate sì che entrambi i limiti di parola diventino una con­di­zio­ne che, nel caso del­l'e­sem­pio uti­liz­za­to, rende l'ar­ti­co­lo in­de­ter­mi­na­ti­vo "un" l'unico risultato possibile:

\bun\b

Rimuovere il me­ta­si­gni­fi­ca­to di caratteri speciali

Nella sezione pre­ce­den­te, la barra ro­ve­scia­ta ha conferito alla "b" seguente non solo il valore di lettera, ma anche quello di me­ta­ca­rat­te­re. Se combinato con caratteri che di norma ap­par­ten­go­no ai caratteri speciali di regex sin­tat­ti­ci, esso ottiene l'effetto com­ple­ta­men­te opposto: il carattere viene trattato come letterale. Grazie a questa op­por­tu­ni­tà, un'e­spres­sio­ne regolare vi permette di cercare senza problemi una data concreta:

11\.10\.2019

In questo caso, la data "11/10/2019" concorda con i criteri di ricerca richiesti come unica stringa di caratteri. Senza applicare la barra ro­ve­scia­ta, entrambi i punti avrebbero il valore di se­gna­li­bri per un carattere qualsiasi, rendendo possibili anche i risultati "1101092019“ o "11a10b2019".

"Di­sin­ne­sca­re" espres­sio­ni regolari voraci

Di norma l'impiego di quan­ti­fi­ca­to­ri ("?", "+", "*", "{}") fa sì che un'e­spres­sio­ne sia "vorace" e cerchi la maggiore con­cor­dan­za possibile. Tuttavia, dato che questo com­por­ta­men­to non sempre è de­si­de­ra­to, i quan­ti­fi­ca­to­ri possono essere spe­ci­fi­ca­ti in un'e­spres­sio­ne regolare ar­gi­nan­do­ne la "voracità". Questo processo di modifica viene il­lu­stra­to nel­l'e­sem­pio seguente:

A.*B

Questa espres­sio­ne vorace applicata alla stringa di caratteri "ABCDEB" non in­ter­rom­pe­reb­be la ricerca a "AB", ma in­clu­de­reb­be tra i risultati l'intera stringa di caratteri. Al contrario, se la ricerca dovesse in­ter­rom­per­si dopo aver trovato la prima "B", essa avrà bisogno della modifica citata. A tale scopo, in molti linguaggi (tra cui Perl, Tcl, HTML) il quan­ti­fi­ca­to­re viene po­si­zio­na­to dopo un punto in­ter­ro­ga­ti­vo:

A.*?B

In al­ter­na­ti­va, l'e­spres­sio­ne vorace ori­gi­na­ria può essere so­sti­tui­ta anche dalla seguente espres­sio­ne equi­va­len­te "non vorace" al fine di ottenere lo stesso risultato:

A[^B]*B
N.B.

Il limite delle espres­sio­ni voraci regolari complica l'e­la­bo­ra­zio­ne di un motivo di ricerca ed è pertanto associato a una maggiore durata di ricerca.

Vai al menu prin­ci­pa­le