Compago

...free knowledge

 
  • Increase font size
  • Default font size
  • Decrease font size
Home Manuali Utilità Espressioni regolari con Apache

Espressioni regolari con Apache

E-mail Stampa PDF

Sommario

Introduzione

Un certo numero di direttive del web server Apache permettono o richiedono l'uso delle espressioni regolari (regular expression o abbreviato regexp).
Le espressioni regolari sono usate per determinare se una stringa, così come un URL o un nome utente, rispetta il loro schema.
Questo articolo descrive l'utilizzo delle espressioni regolari in Apache che costituiscono solo un sottoinsieme di tutte quelle che troviamo in ambienti unix, come ad esempio quelle che troviamo nelle linguaggio Perl.

Le espressioni regolari sono un linguaggio che ci consente di determinare se una stringa rientra o no in un determinato schema.
Per esempio se volessimo stabilire se una stringa ha tutti i caratteri minuscoli oppure contiene almeno 3 numeri o se contiene al suo interno la parola "ciao", allora dovremo far ricorso alle espressioni regolari, con le quali effettuare questi tipi di test.
Apache 1.3 usa una libreria di espressioni regolari chiamata hsregex, che è la stessa usata per il comando egrep, o di grep o altri comandi Unix.
Apache 2.0 usa una libreria chiamata "Perl Compatible Regular Expressions" (PCRE), così chiamata perché implementa molte delle caratteristiche delle espressioni regolati usate nel linguaggio di programmazione Perl.
Questo articolo non mostrerà le differenze tra le prime e le seconde librerie, piuttosto considereremo che hsregex sia un sottoinsieme delle PCRE, quindi tutto quello che veniva fatto in apache 1.3 può essere fatto in apache 2.0, ma non è vero il contrario.

Le basi per le espressioni regolari

Per iniziare ad usare le espressioni regolari, bisogna conoscere alcuni concetti chiave che spiegano il "vocabolario" da usare, (vedi Tabella 1 e Tabella 2).

Tabella 1 - Metacaratteri
Carattere Significato
. Corrisponde a qualsiasi carattere. Questo è il carattere jolly
+ Corrisponde ad uno o più volte il precedente carattere specificato. Per esempio, delle parole che rispettano la regexp M+ sono: MM oppure MMM,non la soddisfa invece la semplice M perché non c'è neanche un carattere dopo.
* Corrisponde ad zero o più volte il precedente carattere specificato. Per esempio, delle parole che rispettano la regexp M* sono: MM oppure MMM, ma anche la singola M.
? Rende opzionale il precedente carattere. Cioè la regexp Days? viene rispettata sia da Day che da Days perché la s è opzionale
^ Indica che i caratteri specificati devono apparire all'inizio della stringa. Quindi una regexp ^por è soddisfatta dalla parola porta che inizia con por ma non dalla parola sport.
$ Indica che i caratteri specificati devono apparire a fine stringa. Quindi ay$ è soddisfatta dalla parola day ma non dalla parola days.
\ Serve a trattare un carattere "speciale" per le espressioni regolari come un normale carattere. Quindi se scrivo \. intendo il carattere "." e non il carattere jolly.
| Serve a indicare dei caratteri alternativi. La regexp a|b significa o a o b
[] Carattere classe. Corrisponde a tutti i caratteri contenuti dentro le parentesi quadre. Quindi [abc] viene rispettata da "a", "b","c" invece [abc]+ da più a, b, c o da una loro combinazione. La regexp [^abc] corrisponde a tutti i caratteri tranne la a, b o c.
[a-q] si riferisce a tutti i caratteri compresi tra la "a" e la "q".
[a-zA-Z] si riferisce a tutte le lettere dell'alfabeto sia minuscole che maiuscole. Per la lista delle classi predefinite vedi Tabella 2
() Raggruppa un insieme di caratteri come se fossero una entità unica, così da potervi applicare, per esempio, l'operatore + o ? che non si riferirà più ad un singolo carattere ma all'intero gruppo.
La regexp (pizza)? rende opzionale l'intera parola "pizza"
{} Indica il numero di volte che un carattere deve essere ripetuto. Per maggiori dettagli vedere Tabella 4

 

Tabella 2 - Classi predefinite
[[:alnum:]] Tutti i caratteri alfanumerici
[[:alpha:]] Tutti i caratteri dell'alfabeto
[[:blank:]] Spazio o Tab
[[:ctrl:]] Tutti i caratteri di controllo
[[:digit:]] Tutti i numeri decimali
[[:graph:]] Tutti i non-spazi e i non-caratteri di controllo
[[:lower:]] Tutte le lettere minuscole
[[:print:]] Come graph ma con gli spazi e i tab
[[:punct:]] Tutti i simboli di punteggiatura
[[:space:]] Tutti i caratteri di spaziatura compresi i simboli si newline e return
[[:upper:]] Tutte le lettere maiuscole
[[:xdigit:]] Tutte i caratteri per i numeri esadecimali



Tabella 3 - Caratteri particolari
\t tabulazione (tab)
\n nuova riga (newline)
\r return (CR)
\xhh character with hex. code hh



Tabella 4 - Ripetizioni
a* zero o  più a
a+ uno o più a
a? zero o uno a (a è opzionale)
a{m} esattamente m volte a
a{m,} almeno m volte a
a{m,n} almeno m volte ma meno di n volte a
repetition? tante ripetizioni quanto repetition ma è viene scelta la corrispondenza più breve

 

Esempio di espressioni regolari in una direttiva di redirect

Come esempio possiamo prendere la necessità di occuparsi del supporto di un sito web tramite un reindirizzamento.
Quindi, ad esempio, tutte le richieste che andavano all'indirizzo http://www.example.com/support/ adesso dovrebbero andare al nuovo sito, http://support.example.com/ .
Questo solitamente si fa con la direttiva Redirect :

Redirect /support http://support.example.com/

ma se volessimo reindirizzare sia i siti http://www.example.com/support/ che http://www.example.com/Support/, allora avremo bisogno di usare due volte la funzione Redirect.
Quindi invece di usare la funzione Redirect due volte potremo usare RedirectMatch una volta sola:

RedirectMatch ^/[sS]upport/ http://support.example.com/

Le parentesi quadre indicano una classe di caratteri, dove l'insieme questa volta è composto da solo 2 caratteri "S" e "s" così che lo schema sia rispettato contemporaneamente sia per la parola Support che per la parola support.
Il carattere ^ davanti alla espressione regolare, significa che la direttiva sia applicata solo ad un URL che inizia con quel particolare schema e non a tutti quelli che invece lo contengono.
Un altro esempio interessante potrebbe essere la trasformazione di un URL, in modo da trasformarne una parte, per esempio tutte le volte che viene richiamata una directory books deve essere trasformata in libri, quindi http://miosito.net/books/eneide/page1.html diventerà http://miosito.net/libri/eneide/page1.html.
Per fare questo uso una direttiva RedirectMatch:

RedirectMatch (.*)books(.*) $1libri$2

Vediamo di analizzare meglio questa direttiva. La parte (.*) prima e dopo la parola chiave books indica rispettivamente "tutto quello che c'è prima" e "tutto quello che c'è dopo", ma non solo, infatti quelle stringhe che troviamo prima e dopo la parola books sono memorizzate nelle variabili $1 e $2 , così da poterle utilizzare nella parte successiva della direttiva.
La seconda parte della direttiva infatti ricostruisce l'URL prendendo la prima parte $1 = http://miosito.net/ , aggiungendovi la parola libri e infine accodandovi la variabile $2 = /eneide/page1.html.

Se avessi voluto invece cancellare una parte di URL , ad esempio la parola books, avrei dovuto usare questa direttiva:

RedirectMatch (.*)\books(.*) $1$2

Per testare velocemente la vostra regex vi consiglio vivamente questi siti:

dove verificare subito il risultato, tutto in maniera veloce e gratuita. Per chi volesse conoscere anche gli effetti delle espressioni regolari in java, ruby o .NET ci sono anche questi altri siti web:

Ultimo aggiornamento ( Martedì 19 Aprile 2011 16:12 )  
Loading

Login