RegEx per linguisti Parte 2
Table of Contents
In questa parte 2 vedremo come utilizzare alcuni caratteri speciali per espandere le nostre ricerche con RegEx, e come questi possono essere usati in diversi contesti quando si analizzano dati linguistici.
I caratteri che andremo ad analizzare sono ? e *.
Il carattere ?
Il punto interrogativo si utilizza dopo un carattere per dire "Trova 1 o 0 ripetizioni di questo carattere".
Il primo metodo di utilizzo nella linguistica applicata potrebbe essere di vedere quante volte in un corpus si utilizza acquilone o aquilone (se siete prescrittivisti i risultati potrebbero farvi star male).
Analizziamo il sostantivo prima di tutto e cerchiamo di applicare anche i caratteri speciali [a-z] e + del precedente post.
- Sappiamo che i sostantivi in italiano hanno diversi possibili suffissi, quindi prendiamo solo la radice aquilon in considerazione.
- Sappiamo che vogliamo comunque il resto del sostantivo con qualunque suffisso, quindi aggiungeremo la combinazione di caratteri speciali [a-z]+ (qualsiasi lettera fino al prossimo spazio) alla radice: acquilon[a-z]+.
- Adesso applichiamo ? per trovare sia i sostantivi con radice acquilon[a-z]+ che aquilon[a-z]+. Il carattere che tende ad esserci o non esserci sembra essere la c, quindi il punto interrogativo verrà utilizzato su di esso.
RegEx finale: ac?quilon[a-z]+
Se lo applichiamo al seguente esempio, tutti i sostantivi verranno presi.
import re return re.findall("ac?quilon[a-z]+", "acquilone aquilone acquiloni aquiloni acquiloncini aquiloncini" )
acquilone | aquilone | acquiloni | aquiloni | acquiloncini | aquiloncini |
Più avanzato
Dato che la difficoltà tra quando usare cq e solo q è ben conosciuta in generale, non solo nella parola aquilone (se ci si pensa è una differenza che non è presente nel sistema fonologico), si potrebbe cercare di scrivere un regex abbastanza generico da prendere tutte le parole con la q seguita da una u e vedere se è mai preceduta da una c.
Analizziamo passo per passo:
- q e cq non saranno mai i primi caratteri della parola in questo caso, quindi i primi caratteri saranno altre lettere, che possiamo definire con [a-z]+. (Usiamo [a-z] invece di . perchè quest'ultimo prenderebbe in considerazione anche gli spazi, includendo parole inutili)
- Dopo le altre lettere avremo, in mezzo, q o cq. Applichiamo ? alla c che a volte c'è e a volte no, e sviluppiamo ulteriormente il nostro regex [a-z]+c?q.
- Dopo la q avremo sempre una u in questo caso (visto che ci riferiamo a parole come acqua, aquilone, aquila, acquedotto, ecc…), quindi [a-z]+c?qu.
- Finalmente, il resto dei caratteri possono essere molteplici lettere, quindi useremo nuovamente [a-z]+.
RegEx finale: [a-z]+c?qu[a-z]+
Illeggibile per chi non conosce RegEx, ma non per noi :) potremmo tradurlo come: "Trova ogni parola che inizia con una o più lettere qualsiasi, ma ad un certo punto ha cqu o qu seguiti da qualsiasi altre lettere.".
Testiamolo ora in Python
import re return re.findall("[a-z]+c?qu[a-z]+", "acquilone aquilone casa acqua aqua acquedotto aquedotto aquila acquila acquistare aquistare tacque taque macchina nacquero naquero" )
acquilone | aquilone | acqua | aqua | acquedotto | aquedotto | aquila | acquila | acquistare | aquistare | tacque | taque | nacquero | naquero |
Sembra funzionare bene ed ignora anche le parole che non c'entrano nulla.
Il carattere *
L'asterisco fornisce la stessa funzionalità del +, con la differenza che il + definisce 1 o più di un carattere, mentre * definisce 0 o più di un carattere.
Un buon utilizzo per questo simbolo è nel caso dei prefissi nei numeri di telefono internazionali (il +39 dell'Italia può anche essere scritto come 0039).
- Il numero inizia con 00 oppure no, sappiamo quindi che ci sono più 0 oppure nessuno come primo carattere, quindi applicheremo * allo 0 così 0*.
- Con un numero come 39123123456 possiamo utilizzare le parentesi quadre [], viste la scorsa volta, per definire un range di numeri da 0 a 9 [0-9] per il resto del numero.
RegEx finale: 0*[0-9]+
import re return re.findall("0*[0-9]+", "0039123123456 39123123456" )
Esercizi
- Scrivere un RegEx per trovare sia il verbo accelerare e accellerare e tutte le loro coniugazioni.
- Scrivere un RegEx per trovare tutte le parole con l e m che possono venire erroneamente scritte in doppia e viceversa.
- Scrivere un RegEx per trovare tutte le parole senza m, con una m o con doppia m all'interno della parola (non in posizione iniziale).
- Scrivere un RegEx che trova tutti i numeri che terminano con un 5.