PDA

View Full Version : [PHP] Espressioni regolari help


GordonFreeman
01-12-2010, 18:37
Suggerirei di postare gentilmente un tutorial sulle espressioni regolari in php tramite preg_match nella sezione Corsi, dato che se ne ha bisogno continuamente ma il loro utilizzo non è per niente banale :O
E non ho trovato guide a prova di novizio in giro.
Parlo per l'interesse di tutti ovviamente.

A parte questo, il mio problema è che non riesco a scrivere una semplice espr. reg. per matchare una data in formato gg-mm-aaaa o gg/mm/aaaa

ho provato così, ma non matcha le date corrette


if(preg_match("%([0-9]{2})/([0-9]{2})/([0-9]{4}) | ([0-9]{2})\-([0-9]{2})\-([0-9]{4})%",$data) == 0)
print "Data scorretta";
else
print "ok";


Se invece tolgo il "|" e la parte a destra , matcha correttamente le date nel formato gg/mm/aaaa.
Come faccio ad aggiungere un OR con il formato gg-mm-aaaa ??

Ogni aiuto è apprezzato
grz

MEMon
01-12-2010, 19:06
l'ex regolare va messa tra /

Poi prova questa che è un pò più sofisticata (verifica anche se i numeri inseriti sono accettabili per il loro significato, nel limite del possibile)


if(preg_match("/([0-2]*[0-9]|3[0-1])[-\/](0*[0-9]|1[0-2])[-\/]([0-9]{4})/", $data) == 0){
print "Data scorretta";
}
else {
print "ok";
}

GordonFreeman
01-12-2010, 19:32
l'ex regolare va messa tra /

Poi prova questa che è un pò più sofisticata (verifica anche se i numeri inseriti sono accettabili per il loro significato, nel limite del possibile)


if(preg_match("/([0-2]*[0-9]|3[0-1])[-\/](0*[0-9]|1[0-2])[-\/]([0-9]{4})/", $data) == 0){
print "Data scorretta";
}
else {
print "ok";
}


mmh, non mi convince, se gli passo $data="623fg12-12-1587gds323" il match passa,

poi sul fatto dei delimitatori, non è obbligatorio usare "/", v. qui
http://us.php.net/manual/en/regexp.reference.delimiters.php

MEMon
01-12-2010, 20:35
Ovvio che passa, quella stringa contiene una data valida.

Se la tua richiesta è "voglio matchare una stringa che sia unicamente una data" allora è diverso, basta comunque mettere ^ prima e $ dopo:


^([0-2]*[0-9]|3[0-1])[-\/](0*[0-9]|1[0-2])[-\/]([0-9]{4})$

MEMon
01-12-2010, 20:38
..

poi sul fatto dei delimitatori, non è obbligatorio usare "/", v. qui
http://us.php.net/manual/en/regexp.reference.delimiters.php

Hai ragione, non funziona perchè hai sbagliato proprio la regex.

GordonFreeman
01-12-2010, 21:08
Ovvio che passa, quella stringa contiene una data valida.

Se la tua richiesta è "voglio matchare una stringa che sia unicamente una data" allora è diverso, basta comunque mettere ^ prima e $ dopo:


^([0-2]*[0-9]|3[0-1])[-\/](0*[0-9]|1[0-2])[-\/]([0-9]{4})$


Si la richiesta è quella :)

Scusa la mia noobbità in materia, ma [0-2]* non vuol dire che sono ammesse da 1 a infinite volte delle cifre 0,1,2?
Quindi anche queste che non sono date passerebbero:
000000000000000000000000000-01-2000
1111111111111111111111111111/01/2000

idem per 0*

MEMon
01-12-2010, 21:22
Si la richiesta è quella :)

Scusa la mia noobbità in materia, ma [0-2]* non vuol dire che sono ammesse da 1 a infinite volte delle cifre 0,1,2?
Quindi anche queste che non sono date passerebbero:
000000000000000000000000000-01-2000
1111111111111111111111111111/01/2000

idem per 0*

Si hai ragione scusami, sostituisci tutti i * con {0,1}. Inoltre se vuoi puoi pensare a come migliorarla ancora, ad esempio ora accetta anche 00 come valore, in teoria dovrebbe accettare solo 01 o 1, robe così

GordonFreeman
01-12-2010, 21:38
Si hai ragione scusami, sostituisci tutti i * con {0,1}. Inoltre se vuoi puoi pensare a come migliorarla ancora, ad esempio ora accetta anche 00 come valore, in teoria dovrebbe accettare solo 01 o 1, robe così

Comincio a ingranare..

poi qualche domanda:

$ serve a dire "tutta la stringa deve matchare il pattern, non solo una sottostringa"?

a cosa serve ^ ?

se nella tua espressione avessi sostituito [-\/] con [\/-] sarebbe stato lo stesso?

Scusa per le domande, se vuoi mettimi il link a un tutorial per noob come me, così me lo leggo :)

MEMon
01-12-2010, 21:43
Comincio a ingranare..

poi qualche domanda:

$ serve a dire "tutta la stringa deve matchare il pattern, non solo una sottostringa"?

Vuol dire che quello che lo precede deve trovarsi alla fine della stringa
Esempio con abc$:
xyzabc -> true
xyzabcd -> false


a cosa serve ^ ?

Vuol dire che quello che lo segue deve trovarsi all'inizio delle stringa
Esempio con ^abc;
abcd -> true
xyzabc -> false

Quindi ^abc$ vuol dire che abc deve essere sia l'inizio che la fine di una stringa, cioè la stringa stessa.


se nella tua espressione avessi sostituito [-\/] con [\/-] sarebbe stato lo stesso?
Stessa cosa si, le parentesi quadre matchano ogni carattere che vi è contenuto dentro, è l'ordine non è importante perchè non fa il match di una stringa, ma di ogni carattere.
Esempio [abc] matcha qualsiasi cosa che sia una 'a', una 'b' o una 'c'.

GordonFreeman
01-12-2010, 22:08
Vuol dire che quello che lo precede deve trovarsi alla fine della stringa
Esempio con abc$:
xyzabc -> true
xyzabcd -> false


Vuol dire che quello che lo segue deve trovarsi all'inizio delle stringa
Esempio con ^abc;
abcd -> true
xyzabc -> false

Quindi ^abc$ vuol dire che abc deve essere sia l'inizio che la fine di una stringa, cioè la stringa stessa.


Stessa cosa si, le parentesi quadre matchano ogni carattere che vi è contenuto dentro, è l'ordine non è importante perchè non fa il match di una stringa, ma di ogni carattere.
Esempio [abc] matcha qualsiasi cosa che sia una 'a', una 'b' o una 'c'.

ok dai grazie :D

poi ci sarebbe da dire che l'espressione matcha queste che non sono corrette:

01-01/2000
01/01-2000

perchè devono essere entrambe - o entrambe / , quindi :


^([0-2]{1,1}[0-9]|3[0-1])[-](0{1,1}[0-9]|1[0-2])[-]([0-9]{4}) |
([0-2]{1,1}[0-9]|3[0-1])[\/](0{1,1}[0-9]|1[0-2])[\/]([0-9]{4})$


a parte il fatto che i giorni non dovrebbero valere 00 , come dicevi prima..

MEMon
01-12-2010, 22:10
Non servono le [] se ci metti un solo carattere, e scritta così non va bene perchè non controlli che sia una stringa unica, inoltre {1,1} non ha un senso pratico, puoi anche eliminarlo.

GordonFreeman
01-12-2010, 23:29
Non servono le [] se ci metti un solo carattere, e scritta così non va bene perchè non controlli che sia una stringa unica, inoltre {1,1} non ha un senso pratico, puoi anche eliminarlo.


^([0-2][0-9]|3[0-1])-(0[0-9]|1[0-2])-([0-9]{4})$ |
^([0-2][0-9]|3[0-1])[\/](0[0-9]|1[0-2])[\/]([0-9]{4})$


la accendiamo?

MEMon
01-12-2010, 23:29
^([0-2][0-9]|3[0-1])-(0[0-9]|1[0-2])-([0-9]{4})$ |
^([0-2][0-9]|3[0-1])[\/](0[0-9]|1[0-2])[\/]([0-9]{4})$


la accendiamo?

Pare di si :D