Ce sunt regular expressions.doc

download Ce sunt regular expressions.doc

of 7

Transcript of Ce sunt regular expressions.doc

Ce sunt regular expressions?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 = '[email protected] este adresa mea de email. Poti sa-mi scrii si la [email protected]';$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 respectivaPREG_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!

Regular expressions sau regex-uri, nu sunt altceva decat tipdare de caractere si ajuta la gasirea unui anumit tipar intr-un sir de caractere.

Folosind un regex puteti cauta un anumit tipar intr-un sir de caractere, puteti inlocui un anumit string cu altul sau il puteti imparti in mai multe siruri de caractere.

PHP ofera dous eturi de functii specifice regular expression:

POSIX Regular Expressions

PERL Style Regular Expressions

POSIX Regular Expressions:

Structura POSIX este similara cu expresiile aritmetice: elemente(operator) ce sunt combinate pentru a da o expresie complexa.

Paranteze

Parentezele patrate ([]) au un inteles pecial cand sunt folosite in regex-uri. Sunt folosite pentru a gasi un caracter dintr-un anumit interval.

ExpresieDescriere

[0-9]Cauta orice numar intre 0 si 9.

[a-z]Cauta orice litera intre a si z (lowercase)

[A-Z]Cauta orice litera intre a si z (uppercase)

[a-Z]Cauta orice litera intre a si Z

Intervalele afisate mai sus sunt generale. Puteti folosi intervale proprii (ex: [0-3] sau [b-v], etc).

Cuantificare:

Frecventa sau pozitia specificata in paranteze patrate poate fi denotata cu un caracter specific.

ExpresieDescriere

p+Orice string ce contine cel putin un p

p*Orice string ce contine 0 sau mai multi p

p?Orice string ce contine 0 sau mai multip. Alternativa p*

p{N}Orice string ce contine o secventa N litere p

p{2, 3}Orice string ce contine o secventa de 2 sau 3 p-uri

p{2, }Orice string ce contine o secventa de 2 sau mai multe p-uri

p$Orice string cu p la sfarsit

^pOrice string cu p la inceput

Exemple

ExpresieDescriere

[^a-zA-Z]Orice expresie ce contine orice caracter din intervalele a z si A Z.

p.pOrice expresie ce contine un p, urmat de orice caracter, iar apoi urmat iar de un p.

^.{2}$Orice string de exact 2 caractere.

(.*)orice string pus intre tag-urile p(hp)*Orice string ce contine un p urmat de zero sau mai mutle instante ale secventei hpIntervale PredefinitePentru a va usura munca, exista cateva intervale predefinite.ExpresieDescriere[[:alpha:]]Orice string din intervalul aA-zZ[[:digit:]]Orice string ce contine numere intre 0 si 9[[:alnum:]]Orice string ce contine caractere in intervalele aA-zZ si 0-9[[:space:]]Orice string ce contine spatiu alb.Functii Regexp PHP POSIXPHP ofera 7 functii pentru regex=uri folosind stilul POSIXFunctieDescriereereg()Functia ereg() cauta un anumit string dupa un tipar definit (regex) si returneaza true daca il gaseste, false in caz contrar.ereg_replace()Functia ereg_replace() cauta un anuumit string conform unui tipar definit si il inlocuieste cu un string dat.eregi()Functia eregi() cauta un string conform unui anumit tipar (cautarea nu este case sensitive).eregi_replace()Functia eregi_replace() functioneaza exact ca si ereg_replace(),doar ca nu este case sensitive.split()Functia split() imparte un string in mai multe elemente.spliti()Similar cu split() doar ca nu este case sensitive.sql_regcase()Functia sql_regcase() returneaza expresii in paranteze patrate (cu cate 2 caractere) cu caracterele convertite. (ex: Php 5.0 va returna [Pp] [Hh] [Pp] [ ] [55] [..] [00])PERL StylePERL este similar cu POSIX si sintaxa este interschimbabila, de fapt puteti folosi tot ce am aratat mai sus si in regex-urile PERL Style.Hai sa va explic cateva concepte folosite in regex-urile PERL.MetacaractereUn metacaracter este un simplu caracter cu un backslash inainte avand un inteles special.De exemplu puteti cauta sume de bani folosind metacaracterul \d in urmatorul mod /([\d]+)000/, In cazul asta \d cauta orice incepe cu un numar.Mai jos am scris o lista de metacaractere folosite in regex-urile PERL StyleCaracterDescriere.Un singur caracter.\sUn caracter spatiu (spatiu alb, tab, rand nou).\SUn caracter diferit de un spatiu.\dUn numar (intre 0-9)\DUn caracter ce nu este numar.\wUn caracter din intervalele a-z, A-Z, 0-9 si _\WUn caracter ce nu face parte din intervalele a-z, A-Z, 0-9 si _[aeiou]Un caracter ce face parte din cele date.[^aeiou]Un caracter ce nu face parte din cele date.(foo|bar|baz)Cauta oricare dintre alternativele date.ModificatoriSunt valabili mai multi modificatori ce te pot ajuta sa gasesti un anumit string mai usor.ModificatorDescriereiFace cautarea case insensitivemSpecifica daca un string are o linie noua, iar daca are, caracterele ^ si $ va lua in considerare noua linie.oEvalueaza expresia o singura data.sPermite folosirea .cautarea unu carater de tip linie noua.xPermite folosirea spatiilor albe in expresie, pentru claritate.gGaseste toate potrivirile la nivel global.cgPermite continuarea cautarii chair si dupa ce cautarea globala nu da rezultate.Functii regexp PERL StyleFunctieDescrierepreg_match()Aceasta functie cauta un string si returneaza true daca il gaseste, altfel returneaza false.preg_match_all()Returneaza numarul de cate ori a gasit un anumit string.preg_replace()Functioneaza exact ca si ereg_replace(), cauta un pattern si il inlocuieste.preg_split()Functioneaza exact ca si split(), imparte un string in mai multe elemente.preg_grep()Cauta in toate elementele unui array si returneza toate elementele gasite.preg_quote()Pune un backslash in fata fiecarui caracter ce s-ar putea gasi intr-un regex