Vai al contenuto

Linguaggi ed espressioni regolari

Da Wikiversità, l'apprendimento libero.
lezione
lezione
Linguaggi ed espressioni regolari
Tipo di risorsa Tipo: lezione
Materia di appartenenza Materia: Linguaggi formali e automi
Avanzamento Avanzamento: lezione completa al 100%

In questa lezione analizzeremo la famiglia delle espressioni regolari (in inglese regular expression o, in forma abbreviata, regexp, regex o RE) di cui si invita a leggere come introduzione la relativa pagina di Wikipedia.

Definizione

[modifica]

Formalmente definiamo espressione regolare una stringa r costruita su un alfabeto Σ={a1,a2,...,ak} e in unione ai seguenti metasimboli:

  • ∅: insieme vuoto
  • ∪: unione (notazione alternativa: |)
  • ⋅: concatenazione
  • ∗: star
  • (): parentesi

Una RE è detta ben formata se si presenta in una delle seguenti forme:

  • r=∅
  • r=a, a∈Σ
  • r=(s∪t) o r=(s|t)
  • r=(s⋅t) o r=(st) (notazione alternativa)
  • r=(s)

dove s e t sono a loro volta espressioni regolari. Si noti che la precedenza degli operatori è:

  • ∗
  • ⋅
  • ∪

Definiamo inoltre altri operatori non essenziali ma frequentemente usati, utilizzando solo le proprietà sopra descritte:

  • ε=∅∗
  • r+=r⋅r∗
  • rh=rr...r⏟m (potenza)
  • [r]kn=rk∪rk+1∪...∪rn con n≥k (ripetizione)
  • [r]=ε∪r
  • (0...9)=0123456789,(a...m)=abcdefghijklm (intervalli ordinati)

Altri operatori possono essere quelli insiemistici teorici: intersezione, differenza e complemento. Una espressione regolare che contiene questi operatori è detta espressione regolare estesa. Nota: Il potere espressivo di una RE estesa non è maggiore di quello di una RE standard.

Definizione di linguaggio regolare

[modifica]

Diciamo che un linguaggio è un linguaggio regolare se è denotato da una RE. Formalmente, un linguaggio regolare Lr è un linguaggio su un alfabeto Σ che ha una corrispondente RE in accordo con la seguente tabella:

Espressione Linguaggio
r=ε Lr={ε}
r=a∈Σ Lr={a}
r=s∪t
r=s|t
Lr=Ls∪Lt
r=s⋅t
r=st
Lr=Ls⋅Lt
r=s∗ Lr=Ls∗

Denotiamo con 𝐑𝐄𝐆 la famiglia di tutti linguaggi regolari e con 𝐅𝐈𝐍 la famiglia di tutti i linguaggi finiti (cioè con cardinalità finita).

Allora possiamo dire che:

𝐅𝐈𝐍⊂𝐑𝐄𝐆

(intuibile: un linguaggio finito può sempre essere visto come l'unione di un numero finito di stringhe, ognuna delle quali concatenazione di un numero finito di simboli dell'alfabeto)

Derivare il linguaggio dalla RE

[modifica]

Per derivare il linguaggio dobbiamo definire alcuni concetti supplementari.

Sottoespressione

[modifica]

Definiamo sottoespressione (in inglese subexpression o SE) una ben parentizzata sottostringa di una RE che si presenta nelle parentesi più esterne.

Chiariamo con un esempio. Sia data la RE:

r=(s∪(t⋅(u∪z)+))

questa RE ha due SE: s e (t⋅(u∪z)+), mentre t e (u∪z)+ NON sono SE di r, ma sono SE di (t⋅(u∪z)+).

Versione numerata

[modifica]

Definiamo 'versione numerata di una RE, la RE a cui vengono aggiunti i numeri alle lettere che compongono la RE, in modo da differenziale le lettere uguali. Anche qui chiariamo il concetto con un esempio:

(aa)∗∪(b⋅((cc)+⋅a))

la sua versione numerata è:

(a1a2)∗∪(b1⋅((c1c2)+⋅a3))

Questa notazione è importante per definire l'ambiguità di un linguaggio (introdotta nelle sezioni successive).

Scelta e derivazione

[modifica]

Diciamo che una RE è una scelta (in inglese choice) di un'altra RE nei seguenti casi:

  • ek, 1≤k≤m è una scelta di (e1∪e2∪...∪ek)
  • em=e...e⏟m, m≥1 è una scelta di e+ e e∗
  • ε è una scelta di e∗

Diciamo che una SE e′ deriva da e″ (scritto come e′⇒e″ se:

  • e″ è una scelta di e′;
  • oppure, e′'i è una scelta di e'i per ogni 1≤i≤m

La derivazione può avvenire più volte allo stesso modo. In questo caso scriviamo:

  • e0⇒nen
    • se e0⇒e1, e1⇒e2, ..., en−1⇒en con n fisato
  • e0⇒+en
    • se e0⇒e1, e1⇒e2, ..., en−1⇒en con n≥1
  • e0⇒∗en
    • se e0⇒e1, e1⇒e2, ..., en−1⇒en con n≥0

Esempi

[modifica]
  • a∗∪b+⇒a∗
  • a∗∪b+⇒a+
  • a∗∪b+⇒a∗⇒ε o equivalentemente a∗∪b+⇒2ε o ancora a∗∪b+⇒+ε
  • a∗∪b+⇒b+
  • a∗∪b+⇒b+⇒bbbb o equivalentemente a∗∪b+⇒2bbbb o ancora a∗∪b+⇒+bbbb

Linguaggio definito da un RE

[modifica]

Il linguaggio definito da una espressione regolare r è:

Lr={x∈Σ∗|r⇒∗x}

Diciamo che due RE sono equivalenti se definiscono lo stesso linguaggio.

Ambiguità delle RE

[modifica]

Una stringa di un linguaggio regolare può essere derivato dalla RE in modi differenti, cioè attraverso distinte derivazioni. Diciamo che una RE è ambigua se esiste una stringa derivabile attraverso due distinte derivazioni che non differiscono solo dall'ordine di applicazione.

Esempio:

a∗∪(b∗∪a)

Ambigua, due modi di derivazione di a:

  • a∗∪(b∗∪a)⇒a∗⇒a
  • a∗∪(b∗∪a)⇒(b∗∪a)⇒a

Condizione sufficiente affinché una RE sia ambigua, se il linguaggio generato dalla RE in versione numerata include due stringhe che coincidono a meno dei numeri.

Esempio:

a1∗∪(b1∗+∪a2)

Genera:

  1. ε
  2. a1
  3. a1a1
  4. a1a1a1
  5. b1
  6. b1b1
  7. a2
  8. ...

Come si vede eliminando i numeri, la stringa 2 coincide con la stringa 7, perciò la RE è ambigua.

Proprietà di chiusura

[modifica]

«Un insieme è chiuso rispetto a un'operazione se e solo se ogni insieme ottenuto applicando l'operazione ai membri dell'insieme originale, l'insieme ottenuto è contenuto nell'insieme originario»

𝐑𝐄𝐆 è chiuso rispetto alla concatenazione, unione e star (quindi anche per gli altri operatori sopra descritti).

[modifica]

Esempi pratici - https://www.evemilano.com/come-funzionano-le-espressioni-regolari-regex/

Altri progetti

[modifica]