fido.altervista.org

Espressioni Regolari - Metacaratteri - parte 3

Il metacarattere escape \

Che cosa succede se voglio cercare un carattere che viene visto dalle regex come un metacarattere? Se per esempio voglio cercare l'indirizzo web dell'agenzia di informazione agi.it, usando la regex agi.it potrebbe capitarmi di avere risultati di questo tipo:
...l'agilità di Biagi italiano ...
Infatti nelle regex il punto è un metacarattere, col ben preciso significato di rappresentare un qualunque altro carattere, spazio compreso.

Allora come si può fare? Bisogna indicare nella regex che ora si vuol usare un carattere nel suo significato letterale, togliendogli ogni 'potere' di metacarattere. Questo lo si fa grazie al metacarattere escape (nel significato di 'fuoriuscita', 'perdita') rappresentato dalla barra rovesciata: \. Quando un metacarattere è preceduto da \, perde il suo significato di metacarattere, tornando ad avere il suo significato letterale, e si dice escaped.
Quindi, per quanto riguarda il punto, l'esempio precedente va scritto agi\.it .

Naturalmente anche il metacarattere \ può essere escaped.
Volendo trovare file del tipo \mio.txt, scriveremo: \\mio\.txt .

In \* l'asterisco è escaped, in \\* no, lo è la barra rovesciata.

Se distrattamente si mette \ davanti a un carattere letterale, \ viene ignorato, a meno che quel carattere non diventi un carattere speciale (vedi caratteri speciali).
Quindi \v, pur non avendo molto senso, equivale a v .

Vediamo un esempio un po' complicato.
Devo limitare l'input di un utente ai soli numeri, anche decimali (usando il punto come separatore decimale). La regex deve cioè indicare come accettabili solo valori del tipo: 0.24, 642, 87.06, 0, 9.5, 7.006, ecc.
Dovendo limitare l'input, la regex contiene i metacaratteri di inizio e fine linea:
^ e $ .
Poi consideriamo il numero diviso in due gruppi: una parte intera e una (eventuale) parte decimale. Per la parte intera, indico una o più occorrenze dei caratteri numerici:
([0-9]+) .
Sembra andare bene, però mi accorgo che così accetta anche numeri che iniziano con uno o più zeri, come 000, 007, o 01. Volendo evitarlo, costruisco un'alternativa: uno zero da solo, o un numero di una o più cifre che non inizia con zero:
(0|[1-9][0-9]*) .
Ora consideriamo la parte decimale: è un gruppo di caratteri che inizia con il punto decimale e prosegue con una o più cifre; essendo un gruppo opzionale lo facciamo seguire dal punto interrogativo: (\.[0-9]+)? .
In conclusione, la regex è:
^(0|[1-9][0-9]*)(\.[0-9]+)?$ .

Qualcuno avrà notato l'uso delle parentesi tonde: (parte intera) (parte decimale). Sono necessarie? Per la parte decimale sì, perché sono seguite dal metacarattere ? che serve a rendere opzionale tutta la parte decimale. Per la parte intera, in questo esempio non sarebbero necessarie, ma si possono ugualmente mettere per rendere la regex un po' più leggibile.
Inoltre, raggruppare parti di regex con le parentesi tonde ci fornisce un'altra grande potenzialità, grazie ancora al metacarattere \ : si tratta della backreference, il riferimento all'indietro. Scrivendo una regex possiamo fare riferimento a un gruppo precedente indicandolo con \ seguito da un numero; questo numero indica l'ordine di apparizione del gruppo nella regex. Nell'esempio precedente, se continuassi la regex scrivendo \1 farei riferimento alla parte intera (il primo gruppo), invece scrivendo \2 farei riferimento alla parte decimale (il secondo gruppo).
Ma torneremo su questo argomento più avanti (in riferimenti).

Stop! Svolgi gli esercizi del Gruppo 5

torna su home avanti

Valid XHTML 1.0! indirizzo gmail Valid CSS 2!

© MLC 2003-2004