Sunteți pe pagina 1din 4

Ce sunt regular expressions?

Autor Vlad Fratila

Ultimul comentariu:
"Atentie! daca folositi functia de genu ereg_replace("(0-9)*","$1",$string) o sa iasa
gramezi de $1 boldate in locu numerelor trebuie sa scrieti ereg_replace("(0-
9)*","\\1",$string).Acum avem toate numerele boldate la locu lor :)"

Adauga comentarii
Toate comentariile

Daca ati intalnit termeni ca regex, expresii regulate, patterned search etc, sau
daca ati citit tutorialul despre mod_rewrite si URLuri frumoase, inseamna ca ati
dat peste niste siruri ciudate de caractere aparent aleatorii.

Expresiile regulate sunt o forma flexibila si puternica de a defini patternuri


(modele) de stringuri. Un string subscrie la un astfel de pattern daca are o
anumita forma, definita in pattern, spre exemplu daca este format din doua litere
de tipar si apoi sase cifre. Daca sunteti atenti, acesta este patternul pentru o serie
de buletin. LLCCCCCC, unde L este o litera de tipar, iar C este o cifra de la 0 la 9.
Daca vrem sa obtinem toate seriile de buletin dintr-un document, tot ce trebuie
sa facem este sa cautam dupa acest pattern.

Sa vedem cum scriem patternul folosind regex.

^[A-Z]{2}[0-9]{6}$

Atat si nimic mai mult. Pare incurcat, dar este de fapt foarte simplu. Sa incercam
sa descifram.

Caracterul ^(carot) marcheaza inceputul stringului, iar $ marcheaza sfarsitul lui.


Intre aceste doua caractere ne vom scrie expresia. Putem renunta la ele, caz in
care expresia se va potrivi oricarei bucati din stringul respectiv.

Parantezele patrate [] reprezinta o secventa de caractere. O putem defini folosind


anumite selectoare, sau scriind direct caracterele la care ne gandim. Daca dorim
ca secventa sa contina doar cifre, putem scrie intre paranteze drepte toate cifrele.
Sau putem folosi un selector: [0-9]. Daca dorim litere mici, [a-z]. Pentru litere
mari, [A-Z]. Aceste selectoare se pot combina, pentru a face ca secventa sa poata
contine toate caracterele specificate de ele: [a-zA-Z0-9_ ] va defini o secventa
care poate contine litere mari, mici, cifre si caracterele “_” si “ ”(spatiu alb).

Acoladele {} contin numarul de caractere pe care il poate avea secventa de text


dinaintea lor. {2} inseamna ca secventa precedenta trebuie sa aiba 2 caractere.
Impreuna, [A-Z]{2} semnifica o secventa de 2 litere mari. Daca dorim sa stabilim
limite de marime, o putem face folosind {2,5} – secventa nu mai mica de 2
caractere si nu mai mare de 5 – sau, dupa caz, limita doar intr-o parte: {2,} –
secventa mai mare de 2 caractere – sau {,2} – secventa mai mica de 2 caractere.

Cu aceasta am incheiat explicatia patternului pentru seria de buletin. Insa puterea


expresiilor regulate nu se opreste aici. Sa explicam o expresie folosita in tutorialul
de rewrite:

RewriteRule ^([a-zA-Z]+)[/]*$

Avem aici doi operatori necunoscuti. + inseamna de fapt {1,} – unu sau mai mult
– iar * {0,} – poate sa existe sau sa nu existe. In loc de * am putea folosi si ?, cu
efectul ca ? se refera la caracterul precedent (deci \/?), pe cand * la secventa
precedenta (deci [/]*). Ati vazut ca am folosit ?\/. Asta deoarece caracterul slash
este caracter de escape. Cu alte cuvinte, daca vrem sa introducem in regex un
caracter rezervat (cum ar fi *,+,/,?, parantezele etc.) trebuie sa-l “scapam” prin
slash, pentru ca parserul regex sa inteleaga ca este vorba de un caracter si nu de
o comanda speciala.

Un alt exemplu. Pentru a gasi toate cuvintele de forma f[cifra sau x] vom folosi
regexul f[0-9x]{1}

Pentru a gasi tot ce are forma f[doua cifre][orice alt caracter] vom folosi regexul
f[0-9]{2}. – inclusiv punctul. Punctul (.) intr-un regex semnifica orice caracter,
mai putin line breaks.

Un ultim lucru: parantezele rotunde pot grupa mai multe secvente, pentru a le
putea aplica aceleasi comenzi. Mai mult, parantezele rotunde vor retine valori.
Daca grupam astfel: ([a-z]+[0-9]+){3}, valorile pe care le va lua paranteza vor fi
stocate in variabila $1. Daca am avea o a doua paranteza, valorile ei ar fi stocate
in variabila $2 si asa mai departe.

Caractere speciale in regex:

* - 0 sau mai multe caractere


+ - 1 sau mai multe caractere
^ - non
\d - o singura cifra
\w - un singur alfanumeric plus underscore
\s - spatiu alb (inclusiv line breaks si tabs)
\t – tab
\n – new line (\r\n pe Windows) – cel mai bine foloseste \s\S
. – orice caracter, mai putin line breaks
| - sau a|b va gasi si a si b
? – ori e, ori nu e, tot aia ;)
Daca doriti sa manipulati texte folosind regexuri, va recomand cu caldura
PowerGREP. Daca vreti sa le folositi cumva in php, haideti sa aplicam ceea ce am
invatat si sa gasim toate adresele de email dintr-o pagina.

Sa stabilim intai regexul pentru o adresa de email:


[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z]{2,4}+

Prima paranteza dreapta este pattern pentru partea de dinainte de arond. Am


folosit + pentru ca secventa trebuie sa contina minim un caracter, fie litera, cifra,
fie –, punct sau _. Urmeaza apoi un arond, si din nou aceeasi secventa, pentru
numele de domeniu. Avem apoi un punct „escaped”, deoarece nu suntem intr-o
secventa [], si apoi tipul de domeniu, care nu poate contine decat 2 pana la 4
litere. Am ales varianta case-insensitive, dar puteti sa schimbati acest lucru, nu?

Sa vedem cum lucram cu PHP. Cel mai simplu si mai rapid, vom folosi functiile
preg, portate din PERL. Asta inseamna ca orice regex va deveni /regex/.

$string = 'vlad@d-d.ro este adresa mea de email. Poti sa-mi scrii si la


bla.bla@yahoo.com';
$emails = array();

Am stabilit stringul in care vom cauta si arrayul in care vor merge emailurile
gasite. Acum nu trebuie decat sa chemam functia:

preg_match_all('/[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z0-9_]{2,4}+/',
$string, $emails, PREG_SET_ORDER);

Aceasta functie are trei flaguri:


PREG_SET_ORDER, pe care l-am folosit, ne intoarce un array asociativ in care vor
fi scrise doar valorile parantezelor din rezultatele gasite, grupate pe rezultat.
PREG_OFFSET_CAPTURE ne va spune in plus numarul caracterului la care incepe
paranteza respectiva
PREG_PATTERN_ORDER ne va intoarce un array simplu cu toate parantezele
gasite, in ordinea din string. Experimentati.

Pentru a vedea daca un string se potriveste unui regex, puteti folosi


preg_match(), care va intoarce numarul de matchuri, deci 0 pentru nici un match,
si FALSE in caz de eroare. Atentie! strpos() sau strstr() sunt mai rapide decat
preg_match(), asa ca daca nu aveti nevoie neaaparata de regex, folositi functiile
de stringuri.

Ce mai este de stiut? Daca doriti un regex find pe un array, este de folosit
preg_grep(), iar daca doriti replace puteti folosi preg_replace(). Succes!
Autor Vlad Fratila

S-ar putea să vă placă și