Creare siti in PHP – (30) – Le espressioni regolari

Siamo arrivati all’ultima puntata di questa guida base al linguaggio PHP, e per concludere affrontiamo oggi un argomento di sicuro non semplice ma che cercheremo di trattare in modo tale da fornire alcuni strumenti utili per la sua comprensione: stiamo parlando delle espressioni regolari. In una sola puntata non riusciremo a trattare l’argomento in modo completo al 100% ma con le nozioni che avremo alla fine potremo eseguire diverse operazioni.
Le espressioni regolari
Per iniziare possiamo dire che cosa sono e a che cosa servono le espressioni regolari. Si tratta di particolari costrutti che si usano per verificare se all’interno di una stringa (e quando in PHP si parla di stringa si intende anche un testo lungo e complesso) è presente una certa sottostringa. Potreste pensare che in realtà non ci sono novità perché abbiamo già visto, nella puntata dedicata alle funzioni sulle stringhe, come cercare e sostituire sottostringhe. In realtà le espressioni regolari sono uno strumento molto più potente perché non definiscono semplici sottostringhe ma, data la loro natura versatile, con un solo pattern (una sequenza di caratteri) possiamo cercare una grande varietà di sottostringhe.
Le espressioni regolari possono essere utili per moltissime situazioni: per esempio, nella puntata in cui parlavamo dei form abbiamo fatto un cenno alle espressioni regolari perché abbiamo detto che servono per controllare se l’utente inserisce un indirizzo email corretto. Questo infatti potrebbe essere un utilizzo, ma potremmo usare le espressioni regolari per altre operazioni, per esempio controllare se un dominio è stato scritto correttamente, evidenziare una certa occorrenza o un insieme di occorrenze in un testo, cercare tutte le etichette HTML presenti in un testo, sostituire doppi apici con virgolette, controllare la complessità di una password e via dicendo.
I metacaratteri
Entriamo subito nell’argomento e iniziamo a parlare di “metacaratteri”, ovvero di caratteri speciali inseriti all’interno di una espressione regolare e che sono dotati di un significato ben preciso. Per esempio la sequenza [a-z] indica “qualsiasi lettera minuscola compresa tra la a e la z”. Se volessimo invece trovare tutte le lettere non solo minuscole ma anche maiuscole dovremmo scrivere un’espressione come questa: [a-zA-Z]. Avrete quindi intuito che le parentesi quadre racchiudono un insieme di caratteri. Vediamo quali sono i metacaratteri:
| [] (parentesi quadre) | Contengono una sequenza di caratteri |
| () (parentesi tonde) | Contengono una precisa sottostringa |
| . (punto) | Qualsiasi carattere |
| ^ (accento circonflesso) | Inizio di stringa o negazione |
| $ (dollaro) | Fine della stringa |
| | (pipe) | Operatore disgiuntivo OR |
| \ (backslash) | Carattere di escape |
I quantificatori
Esistono poi i quantificatori, che indicano quante volte bisogna cercare un’occorrenza all’interno della nostra stringa principale:
| * (asterisco) | Zero o più occorrenze |
| ? (punto interrogativo) | Zero o una occorrenza |
| + (più) | Una o più occorrenze |
| {} (parentesi graffe) | Contengono il numero che rappresenta la ripetizione di un’occorrenza. |
Alcuni esempi…
Facciamo alcuni esempi per comprendere meglio:
| [a-zA-Zàèéìòù0-9] | Tutti i caratteri minuscoli e maiuscoli, le lettere accentate e i numeri |
| [^0-9] | Un qualsiasi carattere che non sia un numero |
| (ciao) | La sottostringa “ciao” |
| t?o | La lettera o preceduta da 0 o 1 occorrenze della lettera t (se il testo è “gatto, canto, albero” ci saranno tre risultati utili e cioè la sequenza “to” di gatto, la sequenza “to” di canto e la “o” di albero) |
| t*o | La lettera o preceduta da 0 o più occorrenze della lettera t (per il testo precedente ci saranno tre risultati utili e cioè “tto” di gatto, “to” di canto e “o” di albero) |
| t+o | La lettera o preceduta da 1 o più occorrenze della lettera t (due risultati utili, “tto” di gatto e “to” di canto) |
| t{2}o | La lettera o preceduta da 2 occorrenze della lettera t (un risultato, “tto” di gatto) |
| t{3,5}o | La lettera o preceduta da un minimo di 3 fino a un massimo di 5 occorrenze della lettera t (nessun risultato) |
| [^t]t{1}o | Un’occorrenza della lettera t seguita dalla lettera o e preceduta da qualsiasi carattere purché non sia una t (un risultato, “to” di canto) |
| [a-s](to) | Qualsiasi carattere compreso tra a e s seguito dalla sottostringa “to” (un solo risultato, “to” di canto). |
| (2\+2) | La stringa “2+2” |
| .$ | Qualsiasi carattere purché sia l’ultimo della stringa |
| (to)|(ro) | La sottostringa “to” o la sottostringa “ro” (tre risultati: “to” di gatto, “to” di canto e “ro” di albero |
… e altri esempi, più pratici
E così via. A questo punto abbiamo quindi gli strumenti per creare dei pattern utili… partiamo dall’esempio più semplice, ovvero un pattern per validare una partita IVA che come tutti sappiamo è composta da undici numeri:
^[0-9]{11}$
Non facciamo altro che creare una sequenza [0-9] che indica un qualsiasi numero, e la facciamo seguire subito dalla sequenza {11} che indica che il numero deve obbligatoriamente occorrere undici volte. L’accento circonflesso e il dollaro indicano ovviamente l’inizio e la fine della stringa. Se omettessimo uno dei due, avremmo vanificato il controllo in quanto potremmo inserire un qualsiasi numero prima o dopo la nostra partita IVA e il pattern verrebbe comunque validato perché il nostro script non saprebbe da dove inizia o dove finisce la stringa.
Possiamo poi creare un pattern che controlli che un dato file sia un’immagine:
^.+\.(jpeg|jpg|png|gif)$
Abbiamo qui il punto che indica una qualsiasi sequenza di caratteri, seguito da un “vero” punto (per essere considerato tale, deve essere preceduto dal carattere di escape) e quindi dalle estensioni tipiche delle immagini “da web” (jpeg, jpg, png, gif) tra parentesi tonde e separate tra di loro per mezzo dell’operatore disgiuntivo.
Prendiamo poi, per esempio, un controllo per validare una data:
^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4}$
In questo caso non facciamo altro che creare tre sequenze [0-9] rispettivamente per i giorni, i mesi e gli anni: nei primi due casi il numero può comparire da un minimo di una a un massimo di due volte e deve essere seguito da un punto (con cui separiamo i numeri della data… gusti personali) a sua volta preceduto da un backslash. Per quanto riguarda l’anno invece il numero deve essere obbligatoriamente presente quattro volte.
Più complesso invece è il pattern per validare un indirizzo email:
^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9_\.\-]+\.[a-z]{2,6}$
Nella prima sequenza tra parentesi quadre inseriamo tutti i caratteri alfanumerici insieme all’underscore, al punto e al trattino e indichiamo che possono ricorrere una o più volte attraverso l’uso del segno +, a fui facciamo seguire la chiocciola. Questa prima sequenza rappresenta il nome utente dell’indirizzo. Dopo la chiocciola inseriamo un’altra sequenza tra parentesi quadre simile alla prima e poi inseriamo il punto preceduto dal carattere di escape. Abbiamo quindi il nome del dominio, a cui facciamo seguire l’espressione [a-z] che può ricorrere da un minimo di 2 fino a un massimo di 6 volte: è nient’altro che l’estensione del dominio.
Le classi di caratteri
Per alcune delle espressioni che abbiamo utilizzato esistono poi le cosiddette “classi di caratteri”, ovvero caratteri che corrispondono a precise sequenze e che possono accorciare molto il nostro lavoro. Vediamone alcune:
| \w | Corrisponde a [a-zA-Z0-9_] |
| \W | Corrisponde a [^a-zA-Z0-9_] |
| \d | Corrisponde a [0-9] |
| \D | Corrisponde a [^0-9] |
| \s | Cerca gli spazi |
| \S | Cerca tutto ciò che non sia uno spazio |
| [:alnum:] | Corrisponde a [a-zA-Z0-9] |
| [:alpha:] | Corrisponde a [a-zA-Z] |
| [:lower:] | Corrisponde a [a-z] |
| [:upper:] | Corrisponde a [A-Z] |
| [:punct:] | Cerca i caratteri di punteggiatura |
Negli ultimi cinque casi, le parentesi quadre sono parte integrante della sequenza, quindi se vogliamo cercare i i segni di interpunzione nella nostra stringa il pattern dovrà essere strutturato in questo modo:
[[:punct:]]
Con le classi di caratteri, le stringhe per la validazione di partite IVA e indirizzi email, tanto per prendere due degli esempi che abbiamo fatto in precedenza, potrebbero diventare una cosa di questo tipo:
^\d{11}$
^\S+@[\w.-]+\.[a-z]{2,6}$
Espressioni regolari e PHP: preg_match e preg_replace
Ma come fare per eseguire il controllo nel nostro script PHP? Abbiamo bisogno di una funzione, preg_match, che riceve come parametri il pattern e la stringa da controllare e nel caso in cui nel testo ci sia almeno una coincidenza con il pattern, la funzione restituirà come risultato 1 (true), e in caso contrario il risultato sarà 0 (false).
Per esempio, poniamo il caso di uno script che controlla se un utente, attraverso un form, ha caricato un’immagine con estensione corretta (il nome dell’immagine sarà stato precedentemente memorizzato in una variabile $immagine).
if (preg_match('/^.+\.(jpeg|jpg|png|gif)$/', $immagine)) {
echo "Grazie per aver caricato l'immagine!";
}
else {
echo "L'immagine ha un'estensione non valida";
}
I due slash inseriti dopo gli apici del primo parametro della funzione sono i delimitatori: se non inseriti, lo script restituirà un errore. Il meccanismo della funzione è molto semplice: il blocco if controlla che il risultato sia true e in caso affermativo stampa la scritta “Grazie per aver caricato l’immagine!”, mentre in caso contrario la scritta mostrata all’utente sarà “L’immagine ha un’estensione non valida”.
La funzione può essere usata anche, ovviamente, nel modo inverso, al negativo, facendo precedere la funzione dal punto esclamativo che indica negazione:
if (!preg_match('/^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9_\.\-]+\.[a-z]{2,6}$/', $indirizzoemail)) {
echo "Indirizzo email non valido";
}
else {
echo "Indirizzo email valido!";
}
In questo caso abbiamo controllato un indirizzo email. La documentazione ufficiale della funzione preg_match si può trovare all’indirizzo http://php.net/manual/en/function.preg-match.php.
Abbiamo detto poi che attraverso le espressioni regolari possiamo poi anche fare sostituzioni all’interno di un testo. Questa operazione si può eseguire attraverso l’utilizzo della funzione preg_replace che riceve tre parametri: l’espressione regolare che definisce le sequenze da sostituire, la sottostringa sostituta e la stringa all’interno della quale compiere la sostituzione. Con un esempio banale:
$testo = "Cane, gatto, topo, cavallo, pecora, mucca";
echo preg_replace ("/[aeiou]/", "*", $testo);
Attraverso l’utilizzo della funzione preg_replace (il cui risultato sarà direttamente stampato attraverso echo) cerchiamo nella stringa $testo tutte le volte in cui occorre una vocale tramite la sequenza [aeiou], e sostituiamo ogni vocale con un asterisco. Questa funzione si presta a diversi utilizzi… per esempio, stiamo costruendo un blog e vogliamo censurare le parolacce dei nostri commentatori (farò un esempio… senza parolacce ma che funziona allo stesso modo).
$testo = "Il gatto mangia il topo";
echo preg_replace ("/(gatto|topo)/", "***", $testo);
In questo caso la parola “gatto” e la parola “topo” vengono sostituite dalla sequenza ***. Possiamo poi adoperare la funzione anche per sostituire etichette HTML:
$testo = "<strong>Ciao</strong>!!!!!";
$testo = preg_replace("/(<strong>)/", "<em>", $testo);
echo preg_replace("/(<\/strong>)/", "</em>", $testo);
In questo caso sostituiamo tutte le parole marcate in grassetto con parole marcate in corsivo. Questi non sono che alcuni esempi, e la versatilità delle espressioni regolari dà modo a ognuno di sfruttarle al meglio per le proprie esigenze. Per chiunque fosse interessato all’argomento, consiglio di approfondire facendo una ricerca sul web: si trovano davvero molti siti che sapranno spiegare meglio di me e in modo più completo l’utilizzo di questo affascinante strumento.
Ciao a tutti!!!
Benissimo, con la puntata di oggi termina anche la nostra guida di base al linguaggio PHP!
Mi auguro che la guida sia stata di vostro gradimento, che possa essere stata utile per imparare qualcosa di nuovo o per ripassare e che possa in generale dare un piccolo aiuto a chiunque voglia cimentarsi con PHP. Ringrazio Laura per avermi fornito questo spazio e ovviamente un grazie a tutti quelli che mi hanno seguito fino a questo punto, a quelli che hanno seguito anche poche puntate, a chi si è collegato una volta sola e a tutti coloro che hanno commentato e hanno tentato di risolvere gli esercizi
Un grande saluto!!!!!!!
Puoi trovare interessante anche:
- Creare siti in PHP – (17) – Alcune funzioni da non dimenticare! Parte 1: funzioni generali e per le stringhe
- Creare siti in PHP – (5) – Le variabili, che cosa sono e a cosa servono
- Creare siti in PHP – (26) – Costruiamo un form di ricerca con PHP/MySQL
- Creare siti in PHP – (16) – Un esempio pratico: controlliamo un form
- Creare siti in PHP – (12) – Cenni sulle funzioni
Esprimi un giudizio sul post!
6 commenti
-
-
27 gennaio 2012 alle 10:46
Grazie soprattutto da parte mia per l’impegno di Federico! Un lavoro preziosissimo messo a disposizione di tutti, scritto in maniera chiara, pieno di esempi, esercitazioni. Non ho parole, semplicemente perfetto
-
27 gennaio 2012 alle 12:14
Grazie anche a te Laura….
Per l’interessante blog…utile e ben disegnato.
Gli unici problemi che ho riscontrato stanno nell’immissione dei codici (html,php) riguardanti gli esercizi di Federico (nel commento), li ha sempre riportati parzialmente, probabilmente per preservare la struttura del sito stesso.
Mi auguro che Federico continui a seguire chi come me è rimasto indietro nell’apprendimento, ed avrà sicuramente altre domande da porgli al riguardo.
Comunque sia un grazie di cuore a tutto lo staff. -
27 gennaio 2012 alle 14:09
altra notifica nell’ ex 16… per Federico…
penserete… minchia che palle questo…
scuse me sin d’ora e grazie per l’attenzione -
2 febbraio 2012 alle 15:34
vorrei tanto impare a fare i siti dinamici…non ho mai tempo, sono un semplice grafico freelance
-
11 febbraio 2012 alle 19:56
Di base… Verrà pubblicata anche una guida avanzata???











Web magazine è il blog personale di
I contenuti di questo blog sono pubblicati sotto licenza
carlo bartolomeo scrive:
26 gennaio 2012 alle 21:51
grazie fede… per l’impegno e la chiarezza.
Per quanto riguarda l’ex della lezione 16… riesco a fare comparire i form in funzione del numero inserito, ma inserendo i dati delle opere all’invio mi rimette solo l’ultimo valore inserito (nell’ultimo campo visualizzato)…
se puoi dai un’occhiata alla lezione 16