Un personaj comun
Validarile din tutorialele precedente au fost simple, constand in mare parte din verificarea existentei unor date de intrare si a corectitudinii lor. Insa, de cele mai multe ori, verificarile pe care le vei face vor fi ceva mai complexe – de exemplu validarea unei adrese de email sau a unui numar de telefon. Pentru a realiza aceste sarcini mai complicate, programatorii au la dispozitie expresiile regulate.
Expresiile regulate reprezinta un mecanism pentru potrivirea si substituirea de sabloane. Ele sunt disponibile atat in editoare cum ar fi vi (pentru Linux), cat si in alte limbaje de programare ca Perl, Javascript, etc. sau in programe shell ca awk si sed. Cam ca Madonna, a carei popularitate nu tine cont de limba si granite teritoriale.
O expresie regulata are rolul de o construi un sablon, utilizand o serie de caractere speciale. Acest sablon poate fi ulterior comparat cu textul dintr-un fisier sau cu datele completate intr-un formular, permitand executarea unor secvente diferite de cod in cazul in care exista sau nu o potrivire. In concluzie, expresiile regulate joaca un rol important in ierarhia de decizii a unei aplicatii.
Un exemplu de expresie regulata este:
al carui simplu scop este de a cauta cuvantul „dragoste” in textul caruia ii este aplicata. Ca si multe alte lucruri in viata, un exemplu concret este mai usor de inteles decat conceptul.
Ce zici de ceva mai greu? Sablonul /fr+/ se va potrivi cu „fraier”, „fumator”, „fular. Iata codul:
<?php
$array = array('fraier', 'fumator', 'fular');
foreach ($array as $element) {
if (preg_match('/fr+/', $element)) echo "$element se potriveste cu sablonul<br />\n";
}
?>
Simbolul + folosit in expresia regulata poarta denumirea de caracter meta – un caracter meta are o semnificatie speciala atunci cand este folosit intr-un sablon. In acest caz, + inseamna una sau mai multe aparitii ale caracterului precedent, de unde rezulta semnificatia expresiei de mai sus : „litera f urmata de una sau mai multe litere r”.
Alte caractere meta sunt * - nici una sau oricate aparitii ale caracterului precedent si ? – nici una sau o aparitie a caracterului precedent. Deci, sablonul /ab*/ se potriveste cu „agresiv”, „absolut”, etc., iar /Ron?/ cu „Ronald”,”Roger”,”Roland”, dar nu si cu „Rimbaud” sau „Mona”.
In cazul in care sabloanele de mai sus ti se par imprecise, expresiile regulate iti ofera posibilitatea de a limita numarul de aparitii ale unui caracter. De exemplu, expresia /ron{2,6}/ se va potrivi ronny si ronnnnnny!, dar nu si cu ron. Numerele dintre acolade reprezinta limitele inferioara si superioara ale numarului de aparitii ale unui caracter.
In plus, poti preciza o serie sau un interval de caractere care vor fi cautate. De exemplu, sablonul /[A-Z]/ se va potrivi cu orice string format din majuscule, /[a-z]/ va gasi toate sirurile de caractere alcatuite din litere mici, iar /[0-9]/ - orice cifra intre 0 si 9.
Utilizand cele trei criterii prezentate mai sus, definirea unui sablon pentru siruri de caractere alfanumerice se face in modul urmator:
Acest sablon se va potrivi cu aB2, dar nu cu abc. Dupa cum poti observa, parantezele patrate au rolul de a diferentia diferitele sectiuni ale unui expresii regulate.
Este de la sine inteles ca ceea ce am discutat pana acum reprezinta doar varful iceberg-ului. Exista un numar mult mai mare de caractere meta si modalitati nenumarate de a le combina in sabloane. Pentru mai multe informatii si exemple de expresii regulate, poti accesa linkurile: http://www.php.net/manual/en/ref.regex.php si http://www.php.net/manual/en/ref.pcre.php.
Definirea unui sablon
In PHP, potrivirea sabloanelor se face apeland una dintre functiile ereg() sau preg_match() (ereg() are si o varianta care nu tine cont de majuscule sau litere mici, denumita eregi()). Aceste functii, ce difera una de alta prin argumentele lor, pot fi utilizate pentru a compara datele introduse de utilizatori cu sabloane predefinite, semnaland erori in cazul in care potrivirea nu este perfecta. Un exemplu des intalnit de utilizare a functiei regex este verificarea unei adrese de email. Iata deci un exemplu in acest sens:
<html>
<head></head>
<body>
<?php
if (!isset($_POST['submit'])) {
?>
<form action = '<?php $_SERVER['PHP_SELF'] ?>' method = 'post'>
Adresa de e-mail:
<br />
<input type = 'text' name = 'email'>
<input type = 'submit' name = 'submit' value = 'Salveaza'>
</form>
<?php
}
else {
if (!ereg('^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)*\.([a-zA-Z]{2,6})$', $_POST['email'])) {
die("Nu stiu ce e asta, dar sigur nu e o adresa de e-mail! ");
}
echo "Adresa de email {$_POST['email']} este structurata corect. Asta nu inseamna ca si functioneaza!";
}
?>
</body>
</html>
In acest exemplu, sablonul /^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)*\.([a-zA-Z]{2,6})$/ este o expresie regulata ce defineste formatul standard al unei adrese de e-mail user@host. Datele care respecta acest sablon vor fi acceptate; cele invalide vor genera un mesaj de eroare. Poti observa ca ereg() nu are nevoie de aceiasi delimitatori ca varianta mai rapida preg_match(), care returneaza o eroare daca nu intalneste cate un „/” la capetele expresiei.
Iata un alt exemplu care te ajuta sa verifici numere de telefon internationale:
<html>
<head></head>
<body>
<?php
if (!isset($_POST['submit'])) {
?>
<form action = '<?php $_SERVER['PHP_SELF'] ?>' method = 'post'>
Telefon (cu prefix de tara):
<br />
<input type = 'text' name = 'tel'>
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php
}
else {
if (!preg_match('/^(\+|00)[1-9]{1,3}(\.|\s|-)?([0-9]{1,5}(\.|\s|-)?){1,3}$/', $_POST['tel'])) {
die ("Nu stiu ce e asta, dar sigur nu e un numar de telefon international!");
}
echo "{$_POST['tel']} are o structura valida. Asta nu inseamna ca si functioneaza!";
}
?>
</body>
</html>
Daca te vei juca putin cu scriptul de mai sus, vei observa ca el accepta oricare dintre numerele +1.212.1234.4567, +44 1865 123456 si 0091 11 1234 5678... desi fiecare dintre acestea este format diferit. Acest lucru se datoreaza faptului ca in expresia regulata am folosit separatorul |, care functioneaza ca un operator logic OR (SAU) si face posibila definirea mai multor alternative in cadrul aceluiasi sablon.
Evident, daca este necesar, poti restrange aria de actiune a sablonului. De exemplu, daca te afli in India si vrei sa verifici doar numerele de telefon ce provin din aceasta tara, poti introduce restrictia ca datele primite sa inceapa cu 91 (prefixul Indiei).
Ca si exercitiu, vom rescrie cateva exemple prezentate in tutorialele anterioare din aceasta serie utilizand expresii regulate.
Iata o varianta a unui script prezentat aici , in care verificarile se fac apeland functia ereg() in loc de intval(),is_numeric() si isset():
<html>
<head></head>
<body>
<?php
if (!isset($_POST['submit'])) {
?>
<form action = '<?php $_SERVER['PHP_SELF'] ?>' method = 'post'>
Cate sandwich-uri doresti? (min 1, max 9)
<br />
<input type = 'text' name = 'quantity'>
<br />
<input type = 'submit' name = 'submit' value = 'Save'>
</form>
<?php
}
else {
if (!ereg('^[1-9]$', $_POST['quantity'])) {
die('EROARE: Cantitatea introdusa nu este corecta!');
}
echo "Iti pregatesc {$_POST['quantity']} sandwich-uri. Sper ca le poti manca pe toate!";
}
?>
</body>
</html>
Poti observa cum in locul a patru instructiuni conditionale a fost utilizata o singura expresie regulata, rezultand un script mult mai compact. Tocmai aceasta flexibilitate face din expresiile regulate un mecanism important pentru validarile de date.
|