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.

  1. Sappiamo che i sostantivi in italiano hanno diversi possibili suffissi, quindi prendiamo solo la radice aquilon in considerazione.
  2. 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]+.
  3. 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:

  1. 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)
  2. 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.
  3. 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.
  4. 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).

  1. 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*.
  2. 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

  1. Scrivere un RegEx per trovare sia il verbo accelerare e accellerare e tutte le loro coniugazioni.
  2. Scrivere un RegEx per trovare tutte le parole con l e m che possono venire erroneamente scritte in doppia e viceversa.
  3. 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).
  4. Scrivere un RegEx che trova tutti i numeri che terminano con un 5.

Date: 2018-11-18 zo 00:00

Author: Andrew

Other posts