
guide
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Creare pattern di ricerca sfruttando la potenza della libreria Oniguruma
Il potere intrinseco delle espressioni regolari come strumento per aumentare la produttività e facilitare la stesura del codice è stato spesso sottovalutato. Le espressioni regolari vengono teorizzate nel 1940 e dal 1960 fanno il loro ingresso nel mondo dei computer. La popolarità del Perl (1990) trasforma questo tool da dominio esoterico di pochi guru a strumento essenziale per ogni sviluppatore.
In questo articolo ripercorreremo le caratteristiche e la sintassi delle espressioni regolari in chiave Ruby.
Oniguruma è il nome del nuovo engine per le espressioni regolari di Ruby (standard dalla versione 1.9 ma già presente in alcune release successive alla 1.8.1). Questo engine offre alcuni miglioramenti rispetto al precedente come un miglior supporto per la gestione dei charset ed alcune funzionalità avanzate. Per verificare la presenza di Oniguruma è sufficiente eseguire il seguente frammento di codice:
def oniguruma? eval("/(?
Nel caso la vostra installazione corrente non supporti Oniguruma non preoccupatevi, in questo articolo specificherò espressamente quali esempi funzionano solamente con il nuovo engine.
In Ruby un espressione regolare viene delimitata dal carattere slash '/
', ma può essere utilizzato anche il marcatore %r
, ecco alcuni esempi:
Esempio | Risultato |
---|---|
/Ruby/ |
Ricerca la parola 'Ruby' |
/[R|r]uby/ |
Ricerca le parole 'Ruby' o 'ruby' |
/^abc/ |
Ricerca una stringa 'abc' ad inizio linea |
%r(xyz$) |
Ricerca una stringa 'xyz' a fine linea |
%r|[0-9]*| |
Ricerca una sequanza di zero o più cifre |
È inoltre possibile specificare un modificatore (che consiste in una singola lettera) immediatamente dopo un espressione regolare, ecco i modificatori più famosi:
Modificatore | Descrizione |
---|---|
i |
Ignora la differenza fra maiuscole e minuscole |
o |
Effettua eventuali sostituzioni una sola volta |
m |
Modalita multilinea (il . significa 'a capo') |
x |
Modalità estesa |
Ad esempio la seguente espressione regolare ricerca per le parole 'Ruby', 'ruby', 'rUby', 'RUBY', etc.
/ruby/i
Infine Ruby mette a disposizione una classe, Regexp
, per salvare le proprie espressioni regolari, invocando il metodo compile
(che è un alias di new
) possiamo creare una variabile contenente:
Ecco alcuni esempi:
pat = Regexp.compile(/Ruby/) # Salva /Ruby/ pat = Regexp.compile(/Ruby/,Regexp::IGNORECASE) # Salva /Ruby/i # La prossima istruzione salva /Ruby/m con supporto UTF-8 pat = Regexp.compile(/Ruby/,Regexp::MULTILINE,"U")
La classe Regexp
ci dà anche la possibilità, tramite il metodo escape
, di includere nelle nostre espressioni regolari caratteri che normalmente verrebbero interpretati (come ad esempio l'asterisco, il punto di domanda, etc.).
Un'ancora è un'istruzione all'interno di un'espressione regolare che serve per identifare una posizione invece che una particolare sequenza di caratteri, le ancore più famose sono il carattere cappelletto '^
' e il carattere dollaro '$
' che non rappresentano, come erroneamente a volte si è portati a credere, l'inzio e la fine della stringa, bensì l'inizio e la fine di una singola linea all'interno della stringa.
Per dimostrarlo possiamo mandare in esecuzione i seguenti frammenti di codice; ricordiamo che l'operatore =~
esegue l'espressione regolare sulla stringa data e ritorna la posizione del primo elemento che corrisponde alla ricerca effettuata:
stringa = "abcXdefXghi" /def/ =~ stringa # 4 /^def/ =~ stringa # nil - la stringa non inizia con 'def' /ghi$/ =~ stringa # 8 /^abc/ =~ stringa # 0 stringa = "abcndefnghi" /def/ =~ stringa # 4 /^def/ =~ stringa # 4 <- '^' corrisponde ad ogni nuova riga /def$/ =~ stringa # 4 <- '$' corrisponde ad ogni fine riga
Esistono anche altre ancore importanti:
Ancora | Descrizione |
---|---|
A |
Corrisponde sempre all'inizio della stringa |
Z |
Corrisponde sempre alla fine della stringa |
b |
Corrisponde al confine di ogni parola |
B |
Corrisponde ad ogni posizione che non sia il confine della parola |
Cerchiamo di esemplificare le ultime due ancore con un esempio:
str = "questo è un esempio" str.gsub(/b/,"|") # "|questo| |è| |un| |esempio|" str.gsub(/B/,"-") # "q-u-e-s-t-o è u-n e-s-e-m-p-i-o"
I quantificatori servono per identificare pattern ed elementi opzionali all'interno della stringa in esame; con un quantificatore è possibile specifiare le occorrenze che ci si aspetta utilizzando il formato esteso {x,y}
, dove con x
è indicato il numero minimo di occorrenze e con y
il massimo.
# Ricerca per una stringa composta da: # da 1 a 3 '0', un '-', 3 '0', un '-', da 0 a 2 '0' pattern = Regexp.compile(/^0{1,3}-0{3}-0{0,2}$/) pattern =~ "0-000-" # 0 pattern =~ "0000-000-0" # nil
Esistono 3 caratteri speciali che vengono usati come scorciatoie, li elenco di seguito:
Scorciatoia | Significato |
---|---|
* |
sta per {0,} cioè 'zero o più' occorrenze |
? |
sta per {0,1} cioè 'zero o una' occorrenza |
+ |
sta per {1,} cioè 'una o più' occorrenze |
Le classi, che sono specificate all'interno di parentesi quadre, contengono, come il nome stesso suggerisce, una classe di corripondenze tutte ugualmente valide ai fini dell'espressione, ad esempio:
/[aeiou]/ # Ogni singola vocale è una corrispondenza per questa espressione
Il trattino '-
' viene usato all'interno di una classe per esprimere il concetto di range di valori mentre il segno cappelletto '^
', usato all'interno della classe serve a negare la corrispondeza;
/[a-z]/ # Corrispondo a questa classe tutte le lettere # dalla 'a' alla 'z' /[^aeiou]/ # Corrispondono a questa classe tutti gli elementi # eccetto le vocali
Esistono alcune classi predefinite che ci consentono di accorciare il tempo di stesura delle espressioni regolari, ad esempio [[:digit:]]
(equivalente di [0-9]
), o [[:alpha:]]
(equivalente di [a-Z]
).
Le parentesi tonde nelle espressioni regolari servono da sempre per raggruppare parte della corrispondenza in modo da potervi accedere in seguito. Ruby introduce un nuovo modo per accedere a tali frammenti utilizzando il metodo match
che riassume tutte le corrispondenze in un istanza dell'oggetto MatchData
.
Vediamo prima alcuni esempi di utilizzo della modalità "classica"; in questi esempi utilizzeremo i metodi sub
e gsub
, entrambi utilizzano le espressioni regolari per trovare frammenti di testo e sostituirli con quanto passato come secondo parametro, sub
in particolare opera solamente sulla prima occorrenza trovata mentre gsub
su tutte le occorrenze nel testo.
str = "a123b456c678"
str.sub(/(a[0-9]+)(b[0-9]+)(c[0-9]+)/, 'n1=1, n2=2, n3=3')
# "n1=a123, n2=b456, n3=c678"
In questo primo esempio l'espressione regolare raggruppa la stringa in tre blocchi contenenti ognuno una lettera (a,b,c)
e una o piu cifre (quantificatore '+
'). Nel secondo parametro del metodo sub
possiamo quindi accedere ai gruppi utilizzando la sintassi k
dove con k
indichiamo il numero del gruppo che vogliamo richiamare.
Nota: nell'esempio abbiamo usato gli apici singoli per delimitare il testo del secondo parametro; questo perché se avessimo usato i doppi apici avremmo dovuto anteporre un'ulteriore '' al marcatore '
k
' per impedire che Ruby interpretasse lo '' del marcatore vanificandone la funzionalità.
I metodi sub
e gsub
accettano anche un blocco come secondo parametro; in questo caso dovremo utilizzare '$k' come marcatore, ecco un esempio:
str = "mi chiamo Sandro"
str.gsub(/([[:alpha:]]+)/) { "parola:#{$1}" }
# "parola:mi parola:chiamo parola:Sandro"
Come anticipato precedentemente Ruby mette a disposizione nuove tecniche per compiere queste operazioni; utilizzando il metodo match
è possibile manipolare un istanza dell'oggetto MatchData
ottenendo da questo i riferimenti a tutti i gruppi specificati (più altre interessanti informazioni).
str = "alpha beta gamma delta epsilon"
pat = /(b[^ ]+) (g[^ ]+) (d[^ ]+)/
refs = pat.match(str)
# refs.to_a contiene: ["beta gamma delta","beta","gamma","delta"]
Utilizzando la variabile refs
possiamo accedere alle corrispondenze utilizzando i metodi tipici di accesso ad un array.
puts refs[1] # beta puts refs[2...3] # gamma delta
Con begin
, end
e offset
possiamo scoprire la posizione di inizio, fine (o l'intervallo) delle corrispondenze:
p1 = refs.begin(1) # 6 p2 = refs.end(1) # 11 p3 = refs.offset(1) # [6,11]
Con pre_match
e post_match
possiamo infine scoprire i frammenti di stringa che precedono e seguono l'intera corrispondenza:
before = refs.pre_match # "alpha " after = refs.post_match # "epsilon"
Se siamo tra i fortunati utilizzatori di una versione di Ruby con Oniguruma, possiamo benificiare di un'ulteriore funzionalità per accedere ai gruppi che abbiamo specificato nelle nostre espressioni regolari: i named matches
; eccone un esempio:
str = "Io sogno quando dormo" pat = /Io (?<verbo1>[a-z]+) quando (?<verbo2>[a-z]+)/
Nell'espressione precedente abbiamo associato (col costrutto ?<val>
) un nome ai due gruppi definiti in 'pat'. Nel prossimo esempio vediamo come recuperare tali corrispondenze utilizzando il nome associato:
refs = pat.match(str) p1 = refs[:verbo1] # sogno p2 = refs[:verbo2] # dormo p3 = refs[1] # sogno (gli indici sono ancora validi)
In queste poche pagine, abbiamo saggiato la potenza della combinazione tra espressioni regolari e Ruby. Quanto spiegato fino a questo punto è solo una piccola parte dell'universo di possibilità offerto da questo potentissimo tool; basti pensare che è possibile creare espressioni regolari ricorsive, o con sub-espressioni al loro interno!
Se vuoi aggiornamenti su Espressioni regolari con Ruby e Oniguruma inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
Tutti i linguaggi per diventare uno sviluppatore di app per Android.
Come creare applicazioni per il Web con PHP e MySQL per il DBMS.
Tutte le principali tecnologie per diventare uno sviluppatore mobile per iOS.
I fondamentali per lo sviluppo di applicazioni multi piattaforma con Java.
Diventare degli esperti in tema di sicurezza delle applicazioni Java.
Usare Raspberry Pi e Arduino per avvicinarsi al mondo dei Maker e dell’IoT.
Le principali guide di HTML.it per diventare un esperto dei database NoSQL.
Ecco come i professionisti creano applicazioni per il Cloud con PHP.
Lo sviluppo professionale di applicazioni in PHP alla portata di tutti.
Come sviluppare applicazioni Web dinamiche con PHP e JavaScript.
Fare gli e-commerce developer con Magento, Prestashop e WooCommerce.
Realizzare applicazioni per il Web utilizzando i framework PHP.
Creare applicazioni PHP e gestire l’ambiente di sviluppo come un pro.
Percorso base per avvicinarsi al web design con un occhio al mobile.
Realizzare siti Web e Web application con WordPress a livello professionale.
Impariamo ad utilizzare Takamaka, una blockchain Java Full Stack, per scrivere codice Java installabile ed eseguibile su una blockchain
Come realizzare le icone di un’app seguendo le linee guida del Material Design, mantenendo uno stile coerente con Android Lollipop.
Panoramica generale sulle CSS Shapes , proprietà e tecniche di base per realizzare layout creativi in grado di avvicinare il Web alle potenzialità della carta stampata.
Guida a Red Hat Quarkus, uno stack Java Kubernetes nativo pensato per applicazioni serverless e per la realizzazione di microservizi rapidi ed ottimizzati. Una piattaforma concepita per accedere in ambiente Cloud mettendo a disposizione un framework orientato ai microservizi, come ad esempio Spring Boot o Micronaut