regex - expresii regulate

42
7/23/2019 RegEx - Expresii Regulate http://slidepdf.com/reader/full/regex-expresii-regulate 1/42 RegEx Ce este o expresie regulată? O expresie regulată, pe scurt denumită şi RegEx sau RegExp , este un şir de caractere care descrie un model de căutare în alt şir de caractere sau, de ce nu, într-un fişier întreg. Cu ajutorul expresiilor regulate poţi găsi sau înlocui anumite părţi dintr-un text. Sunt o metodă puternică de verificare pentru validitatea adreselor de e-mail, domenii de internet sau coduri poştale. Un e-mail valid trebuie să se muleze pe un model prestabilit. Cu RegEx  putem verifica dacă o adresă e-mail se mulează sau nu se mulează pe respectivul model . Deasemenea cu ajutorul expresiilor regulate  putem să analizăm fişiere tot mai mari de text în căutarea informaţiilor dorite. Există diferite definiţii pentru expresiile regulate, fiecare încercând să delimiteze mai bine acest concept. O definiţie pentru expresiile regulate  este următoarea: o expresie regulată  care se mai numeşte şi pattern , este o expresie care descrie un şir de caractere. Acest şir de caractere se interpretează şi identifică anumite şiruri de caractere. Practic şirul de caractere din şablonul  expresiei regulate  este schema generală sau “formula”. RegEx  a apărut la jumătatea secolului trecut. Primele programe de computer care au folosit forma iniţială a expresiilor regulate  şi căutarea pe patternuri au fost editoarele de text. În editoarele de text, la început, căutarea era făcută doar pe un singur rând iar mai apoi căutările au evoluat până azi când o expresie regulată poate acoperi mai multe fişiere gigantice. În anul 1950 matematicianul Stephen Cole Kleene  descria modele matematice  folosindu-se de aşa zisele seturi regulare . Apoi a apărut limbajul Snobol  care a avut o primă implementare a căutării după paternuri , dar care totuşi nu era aceeaşi treabă cu expresiile regulate  de astăzi. După aceasta Ken Thompson  a construit editorul QED  care avea ca scop să găsească patternuri  în fişiere text. Într-un final s-a ajuns la programul grep care foloseşte expresii regulate. Au apărut şi variaţii dezvoltânu-se alte programe pentru Unix  şi Unix-like OS  şi anume: binecunoscutul vi, Emacs sau AWK. Expresiile regulate de la Perl şi Tcl au fost derivate dintr-o librarie RegEx  scrisă de Henry Spencer. După aceasta s-au adăugat şi alte opţiuni şi motorul de expresii regulate a evoluat pe măsură ce timpul a trecut după necesităţi. Philip Hazel  a dezvoltat PCRE (Perl Compatible Regular Expressions ) care încearcă să se apropie de funcţionalitatea expresiilor regulate din Perl  şi este folosit  în unelte puternice precum PHP  sau serverul Apache  pentru HTTP . Practic expresiile regulate  au apărut iniţial din nevoia de standardizare în matematică şi crearea de formule. Folosirea expresiilor regulate  în documente şi în standarde a început să apară prin anii 1960 şi s-a mărit considerabil în anii 1980 când au fost

Upload: xtitiy6730

Post on 17-Feb-2018

427 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 1/42

RegEx

Ce este o expresie regulată? O expresie regulată, pe scurtdenumită şi RegEx sau RegExp, este un şir de caractere care descrie

un model de căutare în alt şir de caractere sau, de ce nu, într-unfişier întreg. Cu ajutorul expresiilor regulate poţi găsi sau înlocuianumite părţi dintr-un text. Sunt o metodă puternică de verificarepentru validitatea adreselor de e-mail, domenii de internet sau coduripoştale. Un e-mail valid trebuie să se muleze pe un model prestabilit.Cu RegEx   putem verifica dacă o adresă e-mail se mulează sau nu semulează pe respectivul model. Deasemenea cu ajutorul expresiilor

regulate  putem să analizăm fişiere tot mai mari de text în căutareainformaţiilor dorite. Există diferite definiţii pentru expresiile regulate,fiecare încercând să delimiteze mai bine acest concept. O definiţiepentru expresiile regulate   este următoarea: o expresie regulată   carese mai numeşte şi pattern, este o expresie care descrie un şir decaractere. Acest şir de caractere se interpretează şi identifică anumiteşiruri de caractere. Practic şirul de caractere din şablonul   expresiei

regulate este schema generală sau “formula”.

RegEx   a apărut la jumătatea secolului trecut. Primele programe decomputer care au folosit forma iniţială a expresiilor regulate  şicăutarea pe patternuri au fost editoarele de text. În editoarele detext, la început, căutarea era făcută doar pe un singur rând iar maiapoi căutările au evoluat până azi când o expresie regulată poate

acoperi mai multe fişiere gigantice. În anul 1950 matematicianulStephen Cole Kleene   descria modele matematice   folosindu-se de aşazisele seturi regulare. Apoi a apărut limbajul Snobol   care a avut oprimă implementare a căutării după paternuri, dar care totuşi nu eraaceeaşi treabă cu expresiile regulate  de astăzi. După aceasta Ken 

Thompson   a construit editorul QED   care avea ca scop să găseascăpatternuri   în fişiere text. Într-un final s-a ajuns la programul grep

care foloseşte expresii regulate. Au apărut şi variaţii dezvoltânu-sealte programe pentru Unix   şi Unix-like OS   şi anume: binecunoscutulvi, Emacs sau AWK. Expresiile regulate de la Perl şi Tcl au fostderivate dintr-o librarie RegEx   scrisă de Henry Spencer. După aceastas-au adăugat şi alte opţiuni şi motorul de expresii regulate a evoluatpe măsură ce timpul a trecut după necesităţi. Philip Hazel   a dezvoltatPCRE (Perl Compatible Regular Expressions ) care încearcă să se

apropie de funcţionalitatea expresiilor regulate din Perl   şi este folosit în unelte puternice precum PHP   sau serverul Apache   pentru HTTP .Practic expresiile regulate   au apărut iniţial din nevoia destandardizare în matematică şi crearea de formule. Folosireaexpresiilor regulate  în documente şi în standarde a început să aparăprin anii 1960 şi s-a mărit considerabil în anii 1980 când au fost

Page 2: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 2/42

consolidate standarde ca ISO GML . Mai apoi acestea s-au extins şi aucăpătat numele de expresii regulate  de astăzi dar nu s-au depărtatprea tare de la scopul iniţial acela de a crea un şablon  care se poateinterpreta şi pe care se pot mula mai multe răspunsuri posibile.Expresiile regulate  sunt folosite în multe editoare de text cât şi înlimbaje de programare dar şi de scripting. Spre exemplu în PHP   se

folosesc expresiile regulate  pentru a putea manipula textul bazându-ne pe patternuri  sau a găsi anumite şiruri de caractere. Spre exempluPerl , Ruby  şi Tcl   au un puternic motor de expresii regulate construitdirect în sintaxă. Şi utilitarele Unix , care au evoluat din cele mai vechitimpuri folosesc expresiile regulate, spre exemplu ed   şi grep . Aici afost pentru prima dată auzit conceptul de expresii regulate   îninteriorul unor utilitare. După aceea ideea s-a popularizat şi a început

să fie foarte folosit.

Odată cu trecerea timpului oamenii au simţit nevoia săautomatizeze anumite sarcini. Este o muncă extenuantă şi dificilă săcauţi manual într-un bloc mare de text un anumit şir. Cu ajutorulexpresiilor regulate   această muncă se automatizează. Programatorulnu are altceva de făcut decât să caute şablonul care înglobează şir-ul

de text căutat sau şir-urile de text căutate. Cu ajutorul expresiilorregulate  nu numai că putem căuta un anumit şir de text, dar putemcăuta o varietate de şiruri de text care s-ar încadra într-un anumitşablon. Spre exemplu să presupunem că dorim să căutăm toateapariţiile sintagmelor “programator începător ” şi “programator expert “.

 În loc să facem două căutări putem observa similaritatea celor douăsintagme. Cu ajutorul expresiilor regulate  vom face o singură căutare

după şablonul următor programator (începător|expert) . Oaltă aplicaţie a expresiilor regulate  sunt căutările şi modificările detext sau numărul de apariţii ale unui şir de caractere. Aceste aplicaţii,pe lângă altele mai puţin sau mai mult cunoscute, se găsesc înmajoritatea editoarelor de text de pe sistemele Windows   (precumWordpad , Notepad ), sistemele Unix  şi Unix-like   (precum vi , emacs ) şiaşa mai departe. Spre exemplu şi Shell-ul Unix   foloseşte anumite

construcţii ca expresii regulate, care nu fac altceva decât să uşurezeviaţa administratorului în crearea şi automatizarea diferitelor scripturi.Un alt utilitar de Unix   interesant şi totodată util este grep   care a fostproiectat special pentru a manipula expresiile regulate. Chiar numelelui „Get Regular Expression Patterns ” simbolizează şi mai bine acestnume şi anume că el caută texte descrise de o anumită expresieregulată. El poate să caute după o anumită expresie regulată  anumite

şiruri de caractere care ne interesează în mai multe fişiere de peserver. Procesarea şi analizarea fişierelor se face linie cu linie. Acesteafolosesc în spate un motor RegEx   de căutare care permite toateaceste mici automatizări. Unele aplicaţii chiar îţi permit să foloseştiexpresii regulate   pentru o căutare complexă într-un şir de caracteresau fişier. În concluzie o expresie regulată este o metodă ideală de adescrie orice şir de caractere şi este extrem de folositoare atunci

când scriem codul unui program, prelucrăm anumite texte sau în alteaplicaţii diverse. În spatele expresiilor regulate se ascund multelucruri interesante însă pentru a le putea folosi un programator arenevoie decât să cunoască sintaxa   şi contextul  în care aceasta estefolosită. Să nu uităm de unde am pornit, de la formule matematicesau teoria automatelor finite  care are aplicaţii practice în arhitecturasistemelor de calcul.

Page 3: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 3/42

Istoric

Expresiile regulate   îşi au rădăcinile în teoria automatelor, teorie

care studiază maşinile abstracte şi problemele care pot fi rezolvate cu

ajutorul acestora, şi în limbajul pseudocod folosit în programarepentru a prezenta într-un limbaj uşor de înţeles un anumit algoritmsau o anumită tehnică. Teoria automatelor   şi limbajul pseudocod auca scop clasificarea şi reprezentarea abstractă a datelor. În anul 1950matematicianul Stephen Cole Kleene   a descris modelele folosite în

teoria automatelor ca “seturi regulate ”. Limbajul SOBOL   a fost primul

care a implementat o potrivire pe bază de şablon, foarte

asemănătoare dar nu identică cu expresiile regulate. Ken Thompson ,unul din părinţii sistemului de operare UNIX  şi creator al limbajului B ,

predecesorul limbajului C , a implementat în editorul QED   o metodăde potrivire a şabloanelor bazată pe setul regulat al matematicianului

Stephen Kleene . Mai târziu a adăugat această funcţionalitate şi îneditorul de text din UNIX , ed , care a dus mai târziu la crearea

filtrului grep   – un filtru foarte des utilizat în UNIX . De atunci s-au

folosit mai multe variante ale modului de potrivire a şabloanelorimplementat de Ken , printre cele mai cunoscute aplicaţii care auimplementat funcţionalitatea fiind expr , AWK , Emacs , vi   si lex .

Expresiile regulate din limbajele Perl   şi Tcl   sunt derivate dintr-o

implementare a expresiilor regulate scrise de Henrz Spencer . Motorul

de expresii regulate din Perl   a fost mai târziu modificat pentru a se

adăuga noi capabilităţi de funcţionare a şabloanelor ajungând să

difere destul de mult de varianta iniţială. Philip Hazel   a dezvoltat în1997 PCRE (Perl Compatible Regular Expressions ), o librărie scrisă înC   care încearcă să exporte expresiile regulate din Perl   în alte limbaje

sau medii. PCRE   a ajuns datorită flexibilităţii oferite să fie cel maiutilizat mod de scriere a expresiilor regulate.

RegEx   a apărut la jumătatea secolului trecut. Primele programe de

computer care au folosit forma iniţială a expresiilor regulate   şicăutarea pe patternuri   au fost editoarele de text. În editoarele detext, la început, căutarea era făcută doar pe un singur rând iar maiapoi căutările au evoluat până azi când o expresie regulată poateacoperi mai multe fişiere gigantice. În anul 1950 matematicianulStephen Cole Kleene   descria modele matematice   folosindu-se de aşazisele seturi regulare. Apoi a apărut limbajul Snobol   care a avut o

primă implementare a căutării după paternuri, dar care totuşi nu eraaceeaşi treabă cu expresiile regulate   de astăzi. După aceasta Ken 

Thompson   a construit editorul QED   care avea ca scop să găseascăpatternuri   în fişiere text. Într-un final s-a ajuns la programul grep

care foloseşte expresii regulate. Au apărut şi variaţii dezvoltânu-sealte programe pentru Unix   şi Unix-like OS   şi anume: binecunoscutul

Page 4: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 4/42

vi, Emacs sau AWK. Expresiile regulate de la Perl şi Tcl au fostderivate dintr-o librarie RegEx   scrisă de Henry Spencer. După aceastas-au adăugat şi alte opţiuni şi motorul de expresii regulate a evoluat

pe măsură ce timpul a trecut după necesităţi. Philip Hazel   a dezvoltat

PCRE (Perl Compatible Regular Expressions ) care încearcă să seapropie de funcţionalitatea expresiilor regulate din Perl   şi este folosit

 în unelte puternice precum PHP   sau serverul Apache   pentru HTTP .

Practic expresiile regulate   au apărut iniţial din nevoia destandardizare în matematică şi crearea de formule. Folosireaexpresiilor regulate   în documente şi în standarde a început să aparăprin anii 1960 şi s-a mărit considerabil în anii 1980 când au fostconsolidate standarde ca ISO GML . Mai apoi acestea s-au extins şi aucăpătat numele de expresii regulate   de astăzi dar nu s-au depărtat

prea tare de la scopul iniţial acela de a crea un şablon  care se poate

interpreta şi pe care se pot mula mai multe răspunsuri posibile.Expresiile regulate   sunt folosite în multe editoare de text cât şi înlimbaje de programare dar şi de scripting. Spre exemplu în PHP   se

folosesc expresiile regulate pentru a putea manipula textul bazându-

ne pe patternuri  sau a găsi anumite şiruri de caractere. Spre exempluPerl , Ruby  şi Tcl   au un puternic motor de expresii regulate construit

direct în sintaxă. Şi utilitarele Unix , care au evoluat din cele mai vechitimpuri folosesc expresiile regulate, spre exemplu ed   şi grep . Aici a

fost pentru prima dată auzit conceptul de expresii regulate în

interiorul unor utilitare. După aceea ideea s-a popularizat şi a începutsă fie foarte folosit.

Odată cu trecerea timpului oamenii au simţit nevoia să

automatizeze anumite sarcini. Este o muncă extenuantă şi dificilă săcauţi manual într-un bloc mare de text un anumit şir. Cu ajutorulexpresiilor regulate   această muncă se automatizează. Programatorulnu are altceva de făcut decât să caute şablonul care înglobează şir-ulde text căutat sau şir-urile de text căutate. Cu ajutorul expresiilor

regulate   nu numai că putem căuta un anumit şir de text, dar putemcăuta o varietate de şiruri de text care s-ar încadra într-un anumit

şablon. Spre exemplu să presupunem că dorim să căutăm toateapariţiile sintagmelor “programator începător ” şi “programator expert “.

 În loc să facem două căutări putem observa similaritatea celor douăsintagme. Cu ajutorul expresiilor regulate   vom face o singură căutaredupă şablonul următor programator (începător|expert) . O

altă aplicaţie a expresiilor regulate   sunt căutările şi modificările detext sau numărul de apariţii ale unui şir de caractere. Aceste aplicaţii,

pe lângă altele mai puţin sau mai mult cunoscute, se găsesc înmajoritatea editoarelor de text de pe sistemele Windows   (precum

Wordpad , Notepad ), sistemele Unix  şi Unix-like   (precum vi , emacs ) şiaşa mai departe. Spre exemplu şi Shell-ul Unix   foloseşte anumiteconstrucţii ca expresii regulate, care nu fac altceva decât să uşurezeviaţa administratorului în crearea şi automatizarea diferitelor scripturi.Un alt utilitar de Unix   interesant şi totodată util este grep   care a fost

proiectat special pentru a manipula expresiile regulate. Chiar numelelui „Get Regular Expression Patterns ” simbolizează şi mai bine acestnume şi anume că el caută texte descrise de o anumită expresie

regulată. El poate să caute după o anumită expresie regulată  anumite

şiruri de caractere care ne interesează în mai multe fişiere de peserver. Procesarea şi analizarea fişierelor se face linie cu linie. Acesteafolosesc în spate un motor RegEx   de căutare care permite toate

aceste mici automatizări. Unele aplicaţii chiar îţi permit să foloseştiexpresii regulate   pentru o căutare complexă într-un şir de caracteresau fişier. În concluzie o expresie regulată este o metodă ideală de adescrie orice şir de caractere şi este extrem de folositoare atuncicând scriem codul unui program, prelucrăm anumite texte sau în alteaplicaţii diverse. În spatele expresiilor regulate se ascund multe

Page 5: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 5/42

Introducere in PCRE

PCRE (Perl Compatible Regular Expressions ) este o librărie deexpresii regulate scrisă în limbajul C   şi inspirată din interfaţa externă

Perl . Librăria PCRE este scrisă de Philip Hazel . Sintaxa PCRE este multmai puternică şi mai flexibilă decât cea POSIX   şi alte librării deexpresii regulate.Librăria PCRE este deja încorporată în proiecte open-source mari precum limbajul de scripting PHP   sau serverul Apache 

HTTP . Librăria poate să fie folosită în medii precum Windows   sauUnix , Unix-like . PCRE   conţine foarte multe opţiuni unice. Iniţial s-adorit să se asemene cu librăria de expresii regulate de la Perl   însă pe

parcurs treaba a început să capete contur şi să se schimbe. PCRE nuvine cu librăria Unicode compilată precum motoarele RegEx de la altelimbaje ca  Java , XML , .NET . În cazul în care dorim s-o folosim trebuiesă compilăm librăria Unicode cu PCRE. Începân cu Perl 5.10.0 , Perl 

suportă câteva extensii PCRE  dar şi Python  pentru sintaxa RegEx. Deşiprogramtorii de Perl   sunt încurajaţi să foloseasca sintaxa Perl suntprezente şi se pot folosi şi sintaxe de la PCRE.

PCRE are propiul sau API . Distribuţia conţine deasemenea şi unset e funcţii C++   de înveliş care sunt scrise chiar de Google Inc.Deasemenea există un set de funcţii C , de înveliş, care sunt bazatepe sintaxa POSIX. Acestea se găsesc în librăria libpcreposix . Acestefuncţii oferă doar nişte cereri în modul POSIX la interfaţa PCRE.Expresiile regulate tot au sintaxa Perl   şi semantica. API-ul de la

POSIX   este restricţionat şi nu oferă acces total la toate facilităţilePCRE.

La instalarea librăriei PCRE, pe un sistem normal Unix-like , o săgăseşti nişte pagini man al căror nume începe cu “pcre”. Cea care senumeşte doar pcre   listează pe toate celelalte. În plus de aceastădocumentaţie bazată pe pagini man, provenite direct din packet, pcre

mai are fişiere text de documentaţie şi anume doc/pcre.txt şidoc/pcregrep.txt sau doc/pcretest.txt. Acestea sunt în distribuţiasursă. Deasemenea avem şi o documentaţie HTML   care se găseşte îndoc/html şi este instalată în /share/doc/pcr/html. Se pot deasemeneagăsi contribuţii de la user pe siteul ftp://ftp.csx.cam.ac.uk.  În fişierulREADME se găsesc mici descrieri care spun ce sunt aceste distribuţii.Unele descrieri sunt complet scrise acolo altele referă către un link

care duce la descrierea iniţială.UTF-8 permite PCRE

  să procesezecaractere care au valori mai mari decât 255 în şirul de caractere. Deunul singur, PCRE   nu are facilitări de accesare a propietăţilorcaracterelor mai mari decât 255. Documentaţia din fişierele man estesuficientă pentru a descoperi cu ce se mănâncă librăria şi cum se potface adăugiri şi alte chestii interesante. Pentru a instala PCRE pe

Page 6: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 6/42

sistemele care nu sunt UNIX   trebuie să citim documentaţia din fişierulNON-UNIX-USE . Dacă sistemul suportă folosirea utilitarelor configureşi make atunci se poate construi exact ca în sistemele Unix-like . Săpresupunem că deja am instalt librăria PCRE   pe un sistem Unix-like ,acum am ajuns la partea interesantă şi anume testarea: numai aşaputem să vedem dacă librăria abia instalată este funcţională sau nu.

Pentru a testa librăria PCRE  pornim RunTest   (care este un script, careeste creat the procesul de configurare).

Pentru viteză PCRE   foloseşte patru tabele pentru a manipula şi aidentifica acele caractere al căror code point este mai mic decât 256.Librăria PCRE suportă doar verificare RegEx, o chestie pe care o facefoarte bine. Însă nu oferă suport pentru căutare şi înlocuire,

 împărţirea şirurilor de caractere sau alte opţiuni drăguţe de genul. Nupoate să fie vorba de o problemă căci odată înţelese expresiileregulate  oricine îşi poate scrie singur codul pentru aplicaţiilemenţionate mai sus. Dacă avem imaginaţie şi curiozitate putem săscriem o mulţime de expresii regulate   care să ofere cele mai diverseinterpretări şirurilor de caractere. Cum spuneam şi mai devremePCRE-ul iniţial nu are suport Unicode. Dacă încercăm să folosim \p,

\P sau \X   (care verifică orice caracter Unicode spre deosebire depunct care se încurcă la caracterele Unicode care pot fi create dinmai multe code pointuri) librăria va da un mesaj de eroare precum căUnicode-ul nu este compilat, asta dacă nu am compilat deja Unicode-ul în PCRE. Problema nu este aşa de mare pe cât pare. Trebuie doarsă fim atenţi în cazul în care ne legăm de Unicode  să compilămlibrăria. Pentru a include şi caracterele Unicode  trebuie să aăugăm

următoarea comandâ: –enable-unicode-properties . Aceasta implică şisuport UTF-8  chiar dacă explicit tu ai cerut numai Unicode. Totuşi ţi-l oferă. Includerea propietăţilor Unicode  îţi oferă posibilitatea de aadăuga circa 30k de tabele în librăria PCRE. Implicit PCREinterpretează caracterul 10 ca indicator pentru sfârşit de linie. Pentrua folosi newline-ul normal care apare în sistemele Unix-line  putem săcompilăm librăria PCRE cu caracterul 13 (carriage return, CR)

adăugând: –enable-newline-is-cr . Putem totuşi să-l facem sărecunoască orice newline cu următoarea comandă: –enable-newline- 

is-any . Prin intermediul acestei comenzi PCRE-ul va recunoaşte oricesecvenţă newline din Unicode. Spre exemplu în sintaxa PCRE putemlăsa şi comentarii în expresiile regulate. Comentariile de genul

(?#comentariu)   sunt ignorate de motorul RegEx şi şablonuleste doar vizualizat pentru detalii despre expresia regulată. Pe lângă

PCRE  şi .NET , Perl , Python  sau Ruby   folosesc acest tip de comentarii.Ca să facem cest tip de comentarii mai vizibile putem să adăugăm şimodificatorul free-spacing. O altă chestie interesantă despre PCREeste că el suportă grupurile atomice  alături şi de alte limbaje precum

 Java , .NET , Perl   sau Ruby . Majoritatea limbajelor folosesccuantificatorii posesivi  în motorul RegEx. În PCRE modul implicit estemulti-line mode adică modul pe mai multe linii.

 În cazul în care dorim să downloadăm librăria PCRE versiunea 7.8avem o putem face de pe siteul ftp://ftp.csx.cam.ac.uk  folosind FTPanonim. De asemenea putem să dowloadăm librăria şi folosind HTTPde peSourceForge.net.  O versiune precompilată pentru Windows a PCREputem găsi la adresa gnuwin32.sourceforge.net

 În concluzie librăria PCRE este uşor de folosit şi robustă şi ne poateoferi un mod real de a ne rezolva problemele şi a căuta şiruri decaractere. Deşi poate că lipsesc anumite facilităţi minore, unprogramator care ştie cât de cât sintaxa îşi poate scrie propiulşablon.

Page 7: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 7/42

Sintaxa PCRE

Ce este un şablon de căutare? Indiferent că este folosit cu librăriaPCRE sau POSIX un şablon de căutare are aceeaşi utilitate. Cred că un

exemplu ar lămuri mai bine: să presupunem că vrem să verificămdacă o adresă de e-mail este validă. Ca o adresă de e-mail să fievalidă trebuie să arate cam aşa “adresa_email@domeniu ” şi să nuarate aşa “@domeniu ..”. Spre exemplu adresa [email protected] 

pare să se muleze pe primul şablon şi adresa @adresa_nu_e_validă..

pare să se muleze pe al doilea şablon. Prima adresă este validă şi adoua nu. Procesul de verificare a adreselor de e-mail poate fi

automatizat foarte uşor folosind expresiile regulate. Prin intermediulfuncţiilor PCRE   ar trebui să verificăm dacă o oarecare adresă de e-mail se mulează pe şablonul   unei adrese de e-mail valide. Deci

şablonul de căutare la expresii regulate este o matriţă care ajutămotorul RegEx   să interpreteze orice fel de şir de caractere. Şablonulde căutare poate să fie înţeles şi ca o formulă sau o serie desimboluri care interpretate ajung la un şir de caractere. Prin

intermediul acestor şabloane se pot face căutări în şirurile decaractere sau în fişiere mari.

Timpul de execuţie creşte sau scade în funcţie de modul în careoptimizăm şablonul de căutare. Şabloanele de căutare pot fi de lacele mai simple exemple cum ar fi caracterul literal “d ” care

returnează orice character literal dintr-un şir de caractere până la

combinaţii complexe. Un şablon de căutare poate să conţină clase decaractere, negări de clase de caractere, alternări, caractere Unicode şimulte altele. Modul în care este construim depinde doar denecesităţile noastre din acel moment şi imaginaţie. Expresiile regulate

sunt o sintaxă care ne permite să facem următoarele chestii:comparaţii complexe de şiruri de text, selectări de şiruri de text saumodificarea acestora.

Puterea expresiilor regulate vine de la abilitatea de a include

alternative   şi repetiţii în şablonul de căutare. Aceste alternative,

repetiţii de text sunt codificate în şablon   folosind meta-caracterele.

Meta-caracterelor   nu înseamnă un text anume care trebuie căutat cise interpretează într-un anume fel, practic ţin locul altor bucăţi detext. Un exemplu ar fi de folos: să presupunem că avem şablonulprogramator. . Textul programatore   se mulează perfect pe

şablonul din exemplu. Dar şi textele programatorb , programatorc .

Observăm că într-un şablon   folosit de expresiile regulate, avem o

bucată de text care se interpretează aşa cum este (programator   se

interpretează programator   la căutarea şirului de text) şi un punct care

se interpretează ca orice caracter. Punctul este un meta-caracter. Deci

Page 8: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 8/42

meta-caracterul este un caracter   care are un înţeles special pentrumotorul expresiilor regulate. Totodată meta-caracterul este şi un primtip de sintaxă. Sintaxa   este poate cel mai important lucru înexpresiile regulate. Fără sintaxa   potrivită sau fără cunoaştereasintaxei potrivite, expresiile regulate  s-ar putea să nu funcţioneze aşacum ne aşteptăm sau s-ar putea să nu funcţioneze deloc.

Haideţi să vedem câteva caracteristici importante are PCRE

referitoare la şabloane şi sintaxă:

reguli de scăpare bine puse la punct: ca şi Perl , PCRE  are regulide scăpre bune. Orice caracter care nu este alfa-numeric poatesă fie scăpat (escaped) ca să însemne valoare literală. Scăparease face cu ajutorul backslashului. Spre exemplu dacă vrem ca unanumit meta-caracter să fie considerat ca şi caracter literal şi nuspecial, atunci este nevoie să-i facem o scăpare cu unblackslash înainte;

clasele de caractere extinse: clasele de caractere care au doarun singur caracter sunt suportate pe lângă denumirile mai lungiPOSIX. Spre exemplu clasa \d  semnifică orice cifră ca şidigit ar însemna în POSIX [0-9]+pentru expresiile

regulate. Aceste două clase înseamnă acelaşi lucru. Văzându-secă se foloseşte frecvent clasa de caractere

[0-9]  s-adezolvat clasa de caractere \d  care înseamnă acelaşilucru. Desigur că s-au mai dezolvat şi alte astfel de clase decaractere minimale pentru [a-z]  sau [A-Z] .

Verificare minimală: un caracter ?  poate să fie plasat înainte de o secvenţă de repetare pentru a indica faptul ca ceamai mică valoare găsită să fie folosită. Implicit cea mai lungă

valore este folosită şi apoi backtrackingul curge spre valorilemai mici.

Caractere Unicode şi propietăţi: Unicode defineşte câtevapropietăţi pentru fiecare caracter în parte. Bineînţeles că înaintetrebuie să avem compilată librăria Unicode în PCRE ca să neputem folosi de propietăţile Unicode în PCRE .

Verificare pe mai multe linii: ^  şi $  pot să verifice

doar la începutul şirului de caractere şi la sfârşitul şirului decaractere depinzând de cum opţiunile sunt setate.

Newline/breakline opţiuni: atunci când PCRE este compilat sestabileşte implicit un newline. De care newline este depind şi^  (de început de şir de caractere) şi $  (de sfârşit de

şir de caractere). Există mai multe tipuri de newline. În cazul încare avem Unicode putem să folosim o opţiune de encodarepentru a putea verifica deodată orice versiune Unicode de

newline. Fără compilarea de Unicode treaba nu funcţionează şiva cere să se compileze Unicode în PCRE ca să poată fi folosit.

Referinţe înapoi: un pattern poate să refere înapoi la un rezultatvalabil găsit. Mai există şi referinţe înainte care pot fi folosite

 într-un alt rezultat valabil găsit.

Grupuri atomice: grupurile atomice sunt un mod de economisirea timpului de execuţie, deci a minimalizării sau prevenirii

backtrackingului din pattern. Trebuie să avem un plan de bătaiedeştept pentru a putea să optimizăm pe cât se poate expresiaregulată şi timpul de execuţie. Pe lângă grupurile atomice maipot fi folosiţi şi cuantificatorii posesivi şi ei având cam acelaşiscop şi anume minimalizarea timpului de execuţie şi scăpareape cât se poate de backtracking.

Comentarii: se pot face comentarii cu următorul cod direct înexpresia regulată: (?>#comentariu) . Aceste comentarii

 împreună cu parantezele rotunde sunt ignorate, deci rămânvăzute doar de programator să-i fie de ajutor în cazul în careexpresia regulată construită este prea complexă sau acestadoreşte ca şi alţi programatori să decodifice mai rapid expresiaregulată.

Page 9: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 9/42

Există şi diferenţe faţă de motorul RegEx de la Perl. PCRE a

evoluat de la Perl   şi apoi a început să evolueze separat, însă nu s-aschimbat major.

Page 10: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 10/42

Caracterul punct in PCRE

Punctul este un meta-caracter  care indică aproape orice altcaracter. Prin cuvântul aproape trebuie să avem în vedere şi

caracterele Unicode  atunci când funcţiile pentru lucrul cu Unicodesunt compilate în PCRE. Ideea este că prin caracter, în variantaUnicode  se înţelege un aşa numit code point. Un caracter Unicode

poate să conţină mai multe codepointuri, spre exemplu caractere cuumlaut din germană. În acel moment punctul  nu identifică chiar orice

caracter   şi în loc să-şi facă treaba în mod corect va identifica altceva.Bineînţeles că la prima vedere un caracter cu umlaut poate părea un

singur caracter dar nu este neapărat aşa şi în variantă practică. DacăPCRE-ul  este compilat şi cu Unicode  atunci putem să folosim un altoperator şi anume \X   pentru a descoperi caracterele. Acest

operator găseşte orice caracter   indiferent dacă are un code point sau

mai multe code pointuri. Trebuie să fim atenţi doar la noanţă şi laceea ce înseamnă un caracter cu adevărat.

Totuşi, dacă ne rezumăm doar la ASCII   punctul ne va fi mai multdecât de ajutor însă folosit cu chibzuinţă. Şi nu numai, punctul este

unul dintre cele mai folosite meta-caractere , tocmai pentru faptul căidentifică aproape orice caracter   şi la prima vedere pare să rezolverapid toate problemele unui programator. Bineînţeles că pe măsură cetrebuiesc filtrate caracterele primite sau căutate punctul nu mai este o

soluţie viabilă. Am scris aproape orice caracter  căci punctul  nu indică

spre caracterele de newline (\n ). Mai pe scurt, punctul  este şi unmeta-caracter  cât şi o clasă negată şi anume: [^\n]   (asta este

pentru UNIX ). Dacă lucrăm pe Windows  observăm că punctul nu indicănici spre \r   deci acolo punctul este o clasă negată   la [^\r\n] .

Motivul pentru care punctul nu indică şi spre aceste caractere (\n şi/sau \r , după caz) este că primele motoare pentru expresii regulate

lucrau linie cu linie. Lucrând linie cu linie era imposibil să se

 întâlnească un newline. Deci treaba este din motive istorice. Ţinemcont totuşi că motoarele moderne de expresii regulate nu mai

lucrează pe un singur rând, ba din contră pe şiruri de text enormesau fişiere mari. De aceea în astfel de motoare moderne se poate

indica ca punctul  să indice şi \n . În Perl , modul în care newline-urile

sunt indicate de punct se numeşte modul “o singură linie ” (single-

line, în engleză). Putem activa după caz modul single-line sau modul

multi-line   fără să apară probleme la interpretarea expresiei regulate. În cazul în care activăm modul single-line meta-caracterul punct din

expresia regulată va indica şi spre newline \n , în cazul în careactivăm multi-line, metacaracterul .   nu va indica şi newline. Înmotorul RegEx de la  JavaScript  şi VBScript  nu avem opţiunea pentru aidentifica sfârşiturile de linie, deci posibilitatea începutului altei linii.

Page 11: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 11/42

 În aceste două limbaje pentru a identifica orice caracter putem săfolosim o clasă ca în exemplul următor: [\s\S] . Asta înseamnăcă această clasă identifică orice caracter care este spaţiu alb sau nueste spaţiu alb, deci orice caracter. Asta include (spre deosebire depunct pe modul single-line) şi identificarea de sfârşituri de linie.

Prin simplul fapt că punctul  permite să identificăm orice caracterne face să fim leneşi, probabil. Dacă suntem la început cu expresiile

regulate   şi ştim că punctul  indentifică orice caracter vom fi tentaţi săadăugăm punct   în mai multe locuri decât este nevoie. Să luăm unexemplu în care punctul  ar putea fi folosit în mod greşit: spreexemplu vrem să delimităm două cuvinte prin slash (/) sau cratima (-). Nu este deajuns să punem punct   între ele programator.bun

caci acesta va indica şi spre programatorabun , ceea ce nu vrem.Caracterul a nu delimitează vizual cele două cuvinte. În loculpunctului, pe care am fi tentaţi să-l folosim ştiind că indică spreorice caracter, putem folosi o clasă de caractere în care includemcaracterele de delimitare prestabilite de noi. Depinde ce vrem săobţinem cu un anumit RegEx   şi contextul în care-l folosim. Dacă,spre exemplu, dorim să delimităm cuvintele programator   şi bun   cu

caracterul a   sau orice alt caracter, atunci putem să folosim şi meta-caracterul punct   în şablon. Dacă vrem să fim mai precişi şi săindicăm anumite caractere pentru delimitare atunci putem folosi clase

de caractere. Să urmărim funcţionarea motorului RegEx   pe următorulşablon cu următorul şir de caractere de căutat: şablon   .+   şişirul programare . Acesta nu va returna niciodată gol căci operatorul

+   trebuie facă ca respectivul caracter interpretat de punct   să

apară cel puţin o dată (nu este neapărat ca acel caracter să aparăconsecutiv, punctul poate interpreta orice caracter şi un răspuns validpoate fi următorul ab1). Asta dacă nu băgăm în seamă treaba cuUnicode  descrisă mai devreme. Trebuie să fim atenţi şi la faptul căoperatorul punct  este unul lacom alături de ?  sau +  şi nuse va opri la primul rezultat valabil şi va mai face backtrackinguri săcaute poate, poate mai există şi alte rezultate la fel de valabile, caz

 în care se va rămâne la ultimul rezultat valabil şi restul vor dispărea.

 Încă un exemplu în care am fi tentaţi să folosim punctul esteurmătorul: să presupunem că vrem să căutăm toate cuvintele care seaflă între ghilimele dintr-o frază. Se dă fraza: Un “programator” bun 

este un programator “bun” . Pare uşor şi un începător în expresii

regulate ar putea scrie un şablon de genul: .*   (putem avea

orice număr de orice caracter cât şi caractere întercalate). La primavedere pare bine, însă expresia “programator” bun este unprogramator “bun” va fi returnată. Dacă disecăm puţin şablonul vomvedea că tocmai această expresie este cea optimă, nu cele douăcuvinte puse între ghilimele pe care am fi vrut să le scoatem înevidenţă. Motivul este că * este greedy   (lacom). Ce înseamnăacest lucru? Procesul va fi repetat ori de câte ori este posibil. Nu este

deajuns că a găsit deja primul cuvânt între ghilimele sau al doilea.Motorul de expresii regulate   va repeta procesul să “vadă” dacă existăşi un al treilea cuvânt (expresie) între ghilimele. Şi chiar dacă este oexpresie, această există şi ea va fi returnată.

Page 12: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 12/42

Caractere si elemente PCRE

Cel mai simplu şablon  folosit într-o expresie regulată  este compusdintr-un singur caracter, de exemplu a . Acest şablon   va indica

către primul caracter a din şirul text pe care aplicăm expresiaregulată. Analog şablonul aa   va indica către şirul de caractere

aa . Oricum expresiile regulate sunt compuse doar dincaractere, totuşi depinde care caracter este cu sensul literal şi care se

interpretează şi în ce fel. Desigur, noi vrem să facem mai mult decât

atât, spre exemplu să indicăm repetiţii de anumite caractere sau

subexpresii. Pentru acest lucru avem nevoie de aşa numitele caractere

speciale. Caracterele speciale   nu sunt altceva decât nişte caractererezervate care au rolul de a desemna o repetiţie, spre exemplu. Sau,

mai pe scurt, caracterele speciale sunt acele caractere care nu seinterpretează literal ci au o semnificaţie simbolică, înseamnă altceva

decât par să însemne la prima vedere. Aceste caractere speciale sunt

descrise minimal în cele ce urmează:

/   indică un delimitator. Acesta este folosit la începutul şi lasfârşitul expresiei (şablonului) pentru a identifica şablonul de căutare.Spre exemplu avem următorul text de căutat: “programator”. Textul

programator este un text oarecare pe când textul

/programator/   este un şablon de căutare pentru expresii

regulate.

.   indică orice caracter (un singur caracter) înafara lui “\n”.Treaba este puţin mai complicată atunci când vine vorba şi e

caracterele Unicode  şi intră în vorbă şi code pointurile. Asta dacă

librăria Unicode este compilată. Voi discuta mai pe larg în cele ce

urmează după prezentarea principalelor caractere speciale.

?   indică repetarea caracterului sau subexpresiei precedente

o dată sau niciodată. Spre exemplu şablonul

/programator(bun)?/   poate indentifica următoarele şiruri de

texte: programator sau programatorbun. Este un operator lacom.

* indică repetarea caracterului sau subexpresiei precedente

niciodată sau de oricâte ori. Spre exemplu şablonul /ab*/

poate însemna abb,a sau chiar abbb (b -ul poate apărea ori de câte

ori în textul căutat sau niciodată)

+  caracterul sau subexpresia precedată apare o dată sau de

mai multe ori (oricâte ori este nevoie). Spre exemplu şablonul

/ab+/  poate identifica abb, abbb  însă nu şi ab.

Page 13: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 13/42

{n}   de câte ori apare caracterul sau subexpresia alăturată.

Spre exemplu a{2}   se găseşte în şirul “aa” dar nu se găseşte

 în şirul a. Nu se găseşte însă în şirul “aaa” căci caracterul sau

subexpresia trebuie să apară de un număr fix de ori în şirul căutat.

{n,}  caracterul sau subexpresia alăturată apare de minim n

ori. Spre exemplu a{2,}   o să se găsească în şirurile aa, aaadar nu şi în şirul a.

{n,m}   caracterul sau subexpresia alăturată apare de minim

n  ori şi de maxim m  ori.

a|b  indică faptul că se caută fie a, fie b.

[abc]   indică orice caracter dintre cele in paranteza pătrata:

a, b, c. Spre exemplu /[abc]/   găseşte pe a   în cuvântul

programator.

[^abc]   indică orice caracter care nu este în setul de

caractere a, b, c.

[a-c]   indică un şir de caractere şi anume toate caracterele

de la a la c: a, b, c.

[^a-c]   indică tot un şir de caractere însă şirul de caractere

care nu include şirul a, b, c. Combinaţiile între clasele sau seturile de

caractere sunt posibile ca în exemplul următor: /[a-c9ef]/ . În

acest caz caracterele din clasă vor fi a, b, c, 9, e, f.

Dacă vrem să folosim oricare dintre aceste caractere în modul

literal, în RegEx, trebuie să indicăm asta într-un fel şi anume un

backslash în faţă. Spre exemplu dacă vrem să căutăm bucata de text

“   Ce faci? ” trebuie să avem în vedere că ?   este uncaracter special şi dacă nu are blackslash în faţă înseamnă altceva

decât ?   la modul literal. RegExul este totuşi valid, însă rezultatul nuva fi cel probabil aşteptat. Dacă adăugăm backslash şablonul o să fie

următorul: Ce faci\? . Dacă eşti programator o să fi surprins

că anumite caractere predestinate în alte limbaje precum ghilimele

simple sau ghilimele duble nu sunt caractere speciale. Nefiindcaractere speciale  nu este nevoie să fie scapăate de ele cu blackslash.

Putem de exemplu, în loc să stăm să scăpăm cu blackslash de fiecare

caracter special în parte să adăugăm \Q   şi \E   la începutul şi la sfârşitul şirului de caractere de care trebuie scăpat

pentru a scăpa de toate şi a ne face viaţa mai uşoară. \E -ul dela sfârşit poate să fie omis deoarece dacă nu există el este

subînţeles.

Putem folosi secvenţe de caractere speciale pentru a adăuga

caractere non-printabile în şablonul unei expresii regulate. Spre

exemplu \t   o să indice spre caracterul tab, \e   către

caracterul escape, \v   pentru un tab vertical sau \n   pentrusfârşit de linie. Putem include orice caracter în expresia regulată dacă

 îi ştim codul ASCII , ANSI   sau Unicode   (dacă suportă motorul deexpresii regulate). Ca să putem folosi caractere Unicode   avem nevoiesă compilăm PCRE cu librăria Unicode căci implicit acesta nu este

compilat. Dacă am compilat suportul pentru Unicode  putem să

introducem caractere în felul următor: \uFFFF . CaractereleUnicode sunt mai degrabă confundate cu code pointuri. Spre exempluse spune că operatorul punct   ar trebui să identifice aproape orice

caracter înafară de newline, însă dacă de exemplu nu avem compilată

libraria Unicode în PCRE   şi avem un caracter cu accent acesta nu va fi

Page 14: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 14/42

bine recunoscut de punct şi expresia regulată nu va returna exact ce

dorim noi să returneze. In Unicode caracterele pot fi formate din maimulte code-pointuri şi deci cum punctul se bazează pe code pointuri(când vinde vorba de Unicode) şi de caractere când vine vorba de

ASCII   nu este o soluţie validă. Există şi sinonimul pentru caractere

Unicode  şi anume \X . Spre exemplu atunci când vrem să

introducem un anumit character şi nu-i găsim semnul pe tastatură

putem oricând introduce doar codul în format hexazecimal.

Odată cu trecerea timpului a fost nevoie de majorarea codului

ASCII   deoarece acesta nu avea loc şi pentru simboluri sau caractere

din alte limbi şi a apărut Unicode. Odată cu caracterele Unicodeapărea şi avantaje şi dezavantaje. Avantajele ar fi că toate ţările îşi au

simbolurile undeva prin code pointurile Unicode   şi o posibilăcomplicaţie ar fi în viziunea programatorului deoarece trebuie să aibă

grijă să identifice correct caractere diverse în diverse formate precum

Unicode.

Page 15: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 15/42

Clase si seturi de caractere PCRE

Prin intermediul unei clase de caractere   (mai este numit şi set de

caractere) putem indica în expresia regulată   un anumit caracter din

mai multe caractere. De exemplu dacă vrem să ştergem toate vocaleledintr-o propoziţie putem folosi un şablon care conţine vocalele.Şablonul ar arăta în felul următor [aeiou] . Desigur aceastăexpresie   o putem intercala într-un şir de text sau într-o altăexpresie precum: progr[aeiou]mator . Această expresie

regulată va găsi şi şirul programator   cât şi sirurile progremator ,

progrimator , progromator , progrumator . Este bine de ţinut minte că

un set de caractere va indica decât un singur caracter, nu mai multe.Nu contează ordinea caracterelor din clasă. În cazul în care vrem caşirul de caracatere indicat să conţină mai multe caractere din clasa decaractere propusă putem să folosim +   (care identifică unul saumai multe caractere din clasa de caractere din faţa acestuia).

Dacă ar fi să definim un set de caractere pentru toate literele din

alfabet, la modul în care este prezentat mai sus, am pierde timpuldegeaba. Seturile de caractere  mai au un caracter special care-şi facebine treaba şi anume - . Dacă vrem să definim toate caracterelede la a la z   este deajuns să scriem şablonul [a-z]   (de la a la

z) în loc să scriem toate caracterele de la a la z. Nu este greşit dacăscriem toate caracterele în set, însă este a doua variantă este maieconomă din punct de vedere al timpului depus. Dacă vrem să

definim toate cifrele putem să scriem şablonul următor [0-9] .Deasemenea putem şi combina mai multe categorii de caractere,

cifre. Dacă vrem să indicăm caracterele de la a la d şi cifrele de la 0la 4 putem să facem în felul următor: [a-d0-4] . Nu este

greşit dacă scriem aşa ceva: [abcd01234]   rezultatul fiind

identic. Putem face şi combinaţii incluzând categorii cât şi caracterede sine stătătoare spre exemplu: [a-dg0-4]   în momentul în

care unul sau mai multe caractere nu intră în nicio categorie. Ordineanu este importantă. Un alt exemplu de combinaţie de caractere şicategorii de caractere ar fi următorul: [^a-zA-Z1234] . Ca

aplicaţie a seturilor de caractere am putea căuta diferite cuvinte sauexpresii chiar dacă nu sunt scrise corect. Se ştie că utilizatorii nuintroduc neapărat o singură formă a unui cuvânt sau expresii şi unmotor de căutare trebuie să dea rezultate optime. Spre exemplu eu

caut cuvântul roşii însă altcineva caută rosi sau roşi. Rezultatultrebuie să fie acelaşi, să ne ducă tot la “conceptul” de roşii, chiardacă sunt câteva caractere în plus sau în minus.

Există şi aşa numitele clase negate   de caractere. Practic toatătreaba stă în faptul că de această dată caracterele din set nu sunt

Page 16: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 16/42

presii regulate

căutate, sunt negate. Orice alte caractere înafară de cele din set suntindicate de respectivul şablon. Important de reţinut că o clasă negatăde caractere va indica tot spre un singur caracter ca şi o clasă decaractere. Dacă vrem să negăm o clasă de caractere trebuie săfolosim un caracter special şi anume ^ . Exemplu:

[^abc] . Orice alt caracter înafară de a,b sau c va fi indicat de

expresia regulată. Putem face şi combinaţii spre exemplu [^a-

c0-9]   sau [^1]   ori [^a-b] . Dacă negăm o categorienegăm toate caracterele din categorie. Primul exemplu şi anume:

[^a-c0-9]   se poate descifra în felul următor: unul dincaracterele de la 0 la 9 dar nu şi caracterele a,b,c. Singurelemetacaractere dintr-o clasă de caractere sunt [] (parantezele care

 închid clasa), \, ^ şi – (pentru a defini o categorie de caractere, de la,

până la). Meta-caracterele sunt caractere normale într-o clasă decaractere   şi nu trebuie să fie indicate printr-un backslash. Spreexemplu pentru a căuta caracterul a sau caracterul ? scriem şablonul

[a?] . Ştim că într-un şir de text oarecare (care nu se află într-o clasă de caractere) dacă vrem să căutăm a?, la modul literal,trebuie să scriem un şablon de genul: a\? . Nu este greşit dacăadăugăm backslash   în faţa meta-caracterelor   dintr-o clasă de

caractere, insă o astfel de clasă de caractere va fi mai greu de citit.Pentru a include \, [, ], – sau ^ în interiorul unei clase de caractere,cu înţeles literal, trebuie să le indicăm cu un backslash   în faţă.Paranteza pătrată de închidere a clasei (]), ^ şi – pot fi incluse şi fărăbackslash însă numai într-o poziţie care nu afectează înţelesul claseide caractere. Spre exemplu un caracter ^ ca să nu fie nevoie debackslash îl putem pune oriunde înafară de început (după paranteza

pătrată de început). Un exemplu valid ar fi următorul [a-c^] .Acesta indică orice caracter dintre a,b,c şi ^. – poate fi incluse dupăparanteza de deschidere sau înaintea parantezei de închidere pentru

a nu fi nevoie de \. Spre exemplu: [-a-b] . Dacă totuşi vremsă-l includem undeva pe la mijlocul clasei de caractere facem în felulurmător: [a-b\-c-d]  pentru a nu strica înţelesul firesc.

Pentru că anumite clase de caractere sunt folosite frecvent saudezvoltat clase de caractere înlocuitoare şi anume \d   este

folosit pentru a indica clasa de caractere [0-9] , \w  este

folosit pentru a indica un caracter dintr-un cuvânt şi anume[a-z,A-z,0-9_] . Aceste clase minimale pot fi incluse atât în

interiorul unei clase de caractere cât şi afară, însemnând acelaşilucru. Aceste clase minimale pot fi şi negate, ca orice altă clasă de

caractere. A nega o clasă \d   înseamnă \D   dar poate însemna şi [^\d] , \W  neagă pe \w .

Dacă repeţi un caracter din clasă folosind operatorii ?,* sau + seva repeta  întreaga clasă şi nu numai primul caracter care este găsitprimul. Spre exemplu [0-3]+   poate identifica în acelaşi timp şi300 şi 221 căci clasa este repetată de fiecare dată (minim o dată) şi

se poate alege de acolo orice alt caracter necontând care estecaracterul de dinainte care a fost găsit în şirul de caractere căutat. Sepot face şi alte adăugiri şi integrări ale claselor de caractere în totfelul de situaţii, depinzând şi de nevoile pe care le are programatorul

 într-un anumit moment. Ca să înţelegem mai bine clasele decaractere putem să observăm şi cum functionează motorul regexatunci când le întâmpină şi luând cât mai multe exemple.

Page 17: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 17/42

Cuantificatori PCRE

Cuantificatorii sunt operatori de repetiţie precum asterixul *

sau plusul + . Operatorii de repetiţie indică   faptul că   ceea ce

este înainte, fie că   este un caracter, o clasa sau o supexpresie, sepoate repeta. Că  se poate repeta o dată   sau de ori de câte ori şi aşamai departe, asta este altă   poveste. Un alt cuantificator este şisemnul întrebării ?   care spune motorului RegEx să   încerce săbifeze caracterul sau supexpresia dinainte niciodată   sau o singurădată. Nu prea este mare repetiţie aici, deci vom trece mai departe.

Să   luăm două   exemple de repetiţie pe cuantificatorul *pentru a înţelege mai bine procesul. Primul este unul simplu şianume: ab* . Acest şablon se poate mula pe următoarele şiruride caractere: a, ab, abb şi aşa mai departe. Asterixul înseamnă   căacel caracter de dinainte se poate repeta de mai multe ori sauniciodată. Dacă  vrem ca o supexpresie să   se repete de mai multe orisau niciodată   putem avea un şablon de genul: a(bc)*   cu

următoarele şiruri de caractere valide găsite: a,abc,abcbc şi aşa maideparte. Deasemenea putem folosi cuantificatorii şi cu clase decaractere dându-ne alte posibilităţi. În loc ca un singur caracter să  serepete tot el, de mai multe ori sau niciodată, se poate ca mai multecaractere distincte sau nu să  se repete şi ăsta este exemplul al doilea

a[a-z]*   poate însemna: a,aa,aab, aac, abcd şi aşa maideparte. Orice caracter din clasa de caractere de la a la z se poate

repeta de ori de câte ori sau niciodată   şi nu trebuie să   fie acelaşicaracter. Repetiţia devine acum un fel de a spune căci nu se mairepetă  acelaşi caracter şi se repetă   un caracter oarecare ori de câteori este nevoie. Modul în care folosim cuantificatorii şi ajutorul pecare ni-l oferă  depinde doar de imaginaţia noastră.

Există  şi cuantificatori care limitează  numărul de caractere care să

se repete. Dacă   la asterix*

aceştia se pot repeta de oricâte orisau niciodată, în cazul operatorului {minim,maxim}   aceştia sepot repeta de între minim şi maxim de ori. În cazul în care nu sefoloseşte un maxim şi se declară   doar minimul caracterul sausupexpresia de dinainte se poate repeta de ori de câte ori, asta dacăse repetă.

Trebuie să  fim atenţi la faptul că  aceşti cuantificatori sunt lacomi.Un cuantificator lacom va încerca să   repete şirul de caractere primitde câte ori este posibil. Un cuantificator care nu este lacom va încercasă   repete şirul de caractere primit de câteva ori şi apoi să   extindă

şirul de caractere rezultat folosindu-se de backtrackingul motoruluiRegEx. Cei lacomi încep cu totul şi apoi mai dau de la ei şi cei care

Page 18: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 18/42

nu sunt lacomi încep cu puţin şi apoi mai iau şi ei ceva. Cam aşastă   şi treaba cu cuantificatorii din spatele motorului RegEx. Săpresupunem că   vrem să   obţinem doar un tag html dintr-un şir detext ca următorul: <b>programator</b>bun . Dacă   vom folosi unşablon cu un cuantificator în felul următor <.+>   vom aveasupriza, dacă   suntem la început, să   observăm că   nu este returnat

<b>   şi <b>programator</b> . Chiar dacă   şablonul pare să   semuleze iniţial numai pe <b>, lăcomia cuantificatorului +   facesă   mai străbată   prin şirul de text în căutarea unui alt şablon care

 începe cu < şi se termină   cu > şi are probabil o lungime mai mare.Cum acesta este găsit şi altele nu mai există, este returnat. Acestlucru se întâmplă   deoarece cuantificatorul întâi repetă  până   la maximtoate caracterele din şirul de text pe care-l primeşte apoi se

 întoarce. După  aceea backtrackingul î şi face meseria aşa cum ştie maibine.

Ca să  scăpăm de această  aşa zisă  problemă  şi putem să   folosimcuantificatorii care nu sunt lacomi şi au un semnul întrebării în faţă.Cu ce ne pot ajuta aceştia în cazul de faţă   şi anume exemplul demai sus: <b>programator</b>bun . Cum menţionasem aş   vrea să

obţin doar primul tag bold şi nu şi cuvântul programator întretagurile bold aşa cum am obţinut cu lăcomia cuantificatorilor. Săconsiderăm următorul şablon: <.+?>   care foloseştecuantificatori care nu sunt lacomi, indicat acest lucru de semnul

 întrebării. Acesta va returna doar <b>. Ca să  înţelegem pe deplin dece se întâmplă   şi cum se întâmplă   acest lucru vom urmări

 îndeaproape cum funcţionează   motorul RegEx pe acest şablon. Ştim

că   +   trebuie să   identifice minimum un caracter şi maximumoricâte caractere. Prima dată  se găseşte în <b> < -ul apoi b, deci segăseşte minimul cerut şi se iese din repetiţia cuantificatorului. Apoise găseşte şi > -ul de închidere. Cuantificatorii care nu sunt lacomi

 î şi fac treaba bine în acest caz. În cazul în care respectivul tag htmlar fi fost <strong> spre exemplu şi textul ar fi fost<strong>programator</strong> tot <strong> s-ar fi obţinut. În

momentul în care s-a îndeplinit minimul cerut, deci caracterul s şi s-a ieşit din repetiţie se verifică  >. După  aceea se reintră   în repetiţie şise verifică  t-ul şi aşa mai departe.

 Înafară   e cuantificatorii lacomi şi cei care nu sunt lacomi maiexistă  şi cuantificatorii posesivi. Aceştia au şi ei un rol important şianume de a reduce timpul petrecut de motorul RegEx prin şirul de

caractere şi a ajunge mai repede la un rezultat valid. Ca rezultatul săfie valid şi din punctul nostru de vedere, ceea ce ne dorim de larezultat, trebuie să  fim atenţi ce tip de cuantificatori folosim.

Există  şi secvenţe de scăpare care indică  anumiţi cuantificatori caşi caractere literare nu cu sensul de cuantificatori. Acestea ne-arputea ajuta în momentul în care şirul de caractere căutat conţine şi

caractere care la modul literar sunt la fel ca şi cuantificatorii folosiţipentru a căuta acele caractere. Modul în care folosim cuantificatorii şila ce îi folosim, dar şi ce tipuri de cuantificatori folosim nu poate fiştiut decât de noi. Nu putem spune că   un cuantificator e mai bunsau mai optim decât celălalt decât într-un anumit context de căutare.Dacă   noi chiar avem nevoie să  căutăm, pas cu pas, printr-un şir decaractere gigant, asta este. Dacă   avem nevoie să  căutăm prin acelaşi

şir de caractere gigant dar s-ar putea să   nu fie nevoie să-ltraversăm pe tot pentru a găsi ceea ce căutăm, asta este un altcontext decât primul.

Page 19: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 19/42

Elemente optionale PCRE

Meta-caracterul ?   indică repetarea o dată sau niciodată acaracterului precedent. Spre exemplu şablonul   programato?r

poate identifica şi şirul de caractere programator cât şi şirul decaractere programatr. Exemplele pot continua. Caracterul o de

dinaintea meta-caracterului ?   poate să lipsească sau să nulipsească dintr-un eventual şir de caractere care să îndeplineascăşablonul dat exemplu. În cazul în care dorim ca mai multe caracteresă apară sau să lipsească dintr-un şir de caractere căutat, putem săgrupăm caracterele în felul următor: programa(tor)? . Acest

şablon va găsi la căutarea într-un şir de caractere atât textulprogramator cât şi textul programa. Sintagma tor poate de dinainteameta-caracterului ?   poate să apară sau să nu apară. Se potface şi combinaţii astfel încât mai multe şiruri de caractere să aparăsau să nu apară într-un eventual şir căutat, ori mai multe şiruri decaractere cât şi anumite caractere să apară sau nu. Totul ţine deimaginaţia sau nevoile programatorului. Spre exemplu putem crea

următorul şablon de căutare: programa(tor)?(bun)?   care vareturna următoarele răspunsuri: programatorbun , programator ,programabun , programa . În cazul în care vrem să verificăm un şir decaractere   şi un caracter   putem crea următorul şablon:

programa(tor)?b(u)?n   care va returna următoarele şiruri decaractere: programatorbun , programatorbn , programabun , programa .

 În momentul în care vrem să facem căutări mai complexe (mai multe

şiruri de caractere, mai multe caracatere care să apară sau nu în şirulrezultat) trebuie să fim atenţi la rezultate.

Meta-caracterul +   indică repetarea   o dată sau de mai multeori a caracterului precedent. Spre exemplul şablonul

programato+r   poate identifica şi şirul programator   dar şiprogramatoor , programatooor   şi aşa mai departe. Totuşi, şablonul  de

mai sus nu va identifica şirul de caractere programatr . Spre exempluputem propune şi expresii care să apară o dată sau de mai multe oricum ar fi programa(tor)+ . Acesta poate să se muleze peşirurile de caractere programator , programatortor , programatortortor 

şi aşa mai departe. Putem face şi combinaţii precum:programa(tor)+(bun)+ . Desigur, în funcţie de necesitate se

pot face combinaţii între diverse meta-caractere, nu numai unul

singur. Mai sunt şi alte astfel de caractere. Trebuie dar să avem grijăcăci în exemplul de mai sus: programa(tor)+(bun)+   sunt

foarte multe şiruri de caracterecare se verifică, defapt numărul loreste nelimitat. Spre exemplu următoarele şiruri de caractere arverifica şablonul: programtorbun , programatorbunbun ,programatortorbun , programatortorbunbunbun   şi aşa mai departe.

Page 20: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 20/42

Desigur că poate să existe şi varianta programatortortortortortorbun 

 însă variante de genul programabun   nu există aşa cum nu există niciprogramatortor   sau programatortortor . Meta-caracterul +   cere

ca subexpresia   sau caracterul de dinainte să fie prezent măcar odatădar poate apărea de un număr nelimitat de ori.Un concept importantdin RegEx   se numeşte greedy   (lăcomie). Meta-caracterul ?   este

unul lacom. ?   oferă motorului RegEx   două posibilităţi: fie căidentifică şi partea de dinainte de paranteză, fie că nu o identificădeloc. Însă motorul RegEx   va încerca de fiecare dată, prima dată, săidentifice şirul de caractere şi şirul de dinainte de metacaracterul

? . De aceea îi spune lacom, căci el prima dată încearcă să“înghită” şi şirul de caractere de dinainte de el (de dinainte de ?) şiapoi, dacă observă că nu are ce înghiţi recurge la a doua variantă. Să

luăm ca exemplu următorul şir de caractere : “un programator bun 

este un programatoreficient ” şi următorul şablon:programator(eficient)? . Motorul RegEx   o să returneze şirul

de caractere programatoreficient   deşi există şi programator. Estelacom, căci el întâi verifică dacă poate să înghită şi ce este înainte şimai apoi, dacă nu găseşte, încearcă a doua variantă. Un exemplu încare ar încerca şi găsi a doua variantă este următorul: se dă şirul de

caractere “un programator bun este un programatoreficien ” şişablonul: programator(eficient) . Cum şirul programatoreficient   nu mai

este găsit se va returna şirul programator . Meta-caracterul ?  nu

este singurul lacom. Şi meta-caracterele * şi   +   sunt

lacome.

Că tot am văzut că aşa numitele caractere literare şi clase de

caractere   identifică un singur caracter sau un singur şir de caractere.Ancorele  identifică o poziţie inainte, după sau între caractere. Ele potfi folosite pentru a ancora rezultatul RegEx   la o anumită poziţie.

^   indică prima poziţie din şirul de caractere. Spre exempluşablonul următor  ^a   identifică şirul de caractere abc   căci îlgăsim pe când şablonul următor  ^b   nu mai identifică şirul decaractere abc   căci nu găseşte pe b   la început, dar ar putea identifica

şirul de caractere bac căci atunci îl găseşte pe b la începutul şirului.Similar $   verifică dacă este la sfârşitul stringului deci a$

nu îl va găsi pe a la sfârşitul şirului de caractere abc .

Comentariile   sunt foarte importante în expresiile regulate foarte

mari unde vrem să înţelegem peste o perioadă de timp ce am făcutsau să le oferim posibilitatea şi altor programatori să înţeleagă codul.

 În cazul în care vrem să adăugăm comentarii scriem#text_comentariu . Un comentariu se scrie în felul următor în

şablon şi anume (?#text_comentariu)   şi este ignorat demotorul RegEx. Acest tip de comentarii  cu care probabil majoritateaprogramatorilor sunt obişnuiţi se găsesc, pe lângă PCRE   şi în motorul

RegEx de la .NET, Perl, Python sau Ruby. Ca să facem mai vizibilăexpresia regulată alături de comentarii  putem să adăugăm şi

modificatorul pentru free-spacing.

In modul freespacing spaţiile goale sunt ignorate. Spaţiile goaleinclud şi space-uri, taburi şi \n –uri. Spre exemplul “a b” este acelaşicu “ab” în acest mod. Modificatorii de grup pentru grupuri atomice nu

pot fi sparţi folosin spaţii. Nici clasele de caractere   nu mai înseamnăacelaşi lucru dacă lasăm spaţii libere în interiorul acestora. În

interiorul classelor de caractere modificatorul free spacing nu areniciun efect. În interiorul expresiilor regulate   se pot introduce condiţiiprecum if,then,else. In cazul în care partea de la if este adevăratăatunci se va încerca evaluarea părţii then şi în celălalt caz evaluareapărţii cu else. Sintaxa   constă într-o pereche de paranteze rotunde.

Dupa paranteza rotundă de deschidere se găseşte un semn de

Page 21: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 21/42

 întrebare. Şi aceste condiţii au multe aplicaţii practice care ne vinimediat în minte precum extragerea headerelor de la emailuri. Alteaplicaţii practice stau la îndemnâna oricui are imaginaţie sau nevoiede a rezolva o anumită cerinţă.

Page 22: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 22/42

Grupuri si referinte PCRE

Dacă vrei să grupezi părţi din expresia regulată o poţi facepunându-le între paranteze rotunde. Asta te ajută să foloseşte o

subexpresie din şablonul expresiei regulate ca un întreg şi la acest întreg să adaugi operatori de repetiţie şi alte lucruri interesante.Numai parantezele rotunde   pot fi folosite pentru gruparea unor părţidin expresia regulată. Restul de paranteze au alte funcţii şi nu pot fifolosite la grupare.

 Înafară de gruparea unei părţi din expresia regulată, parantezele

rotunde   crează şi o referinţă înapoi. O referinţă înapoi reţine parteadin şirul de caractere care se mulează pe partea din expresia regulatădin paranteză. Această operaţie bineînţeles că face ca toată treabamotorului RegEx   să se desfăşoare mai lent căci sunt mai multelucruri de făcut. Cu cât mai multe, cu atât şi timpul este mai mare.Se pot folosi şi paranteze care nu reţin şirul de caractere returnat departea de expresie regulată dintre paranteze şi în acest fel se poate

mări viteze de execuţie. Ca să înţelegem mai bine mecanismul şimodul în care funcţionează gruparea şi referinţele o să luăm unexemplu: fie expresia regulată programator(bun)?   . Aceasta

se mulează pe două şiruri de caractere şi anume programator sauprogramatorbun căci ?   înseamnă că subexpresia sau caracterul

de dinainte se poate repeta o dată sau niciodată. Gruparea unei părţidin expresia regulată, chiar şi o subexpresie   la modul literal o să

reţină şirul de caractere de dinainte, interpretat. În primul caz şirulnu există căci se returnează doar programator însă în al doilea cazacesta există şi este bun, chiar şirul de caractere literal. Putem decisă nu folosim referinţe şi să nu se mai reţină şirul de caractere bunpentru a micşora timpul de execuţie. Bineînţeles că exemplul nu estecomplex, totuşi la şiruri de caractere mari sau la fişiere timpul deexecuţie ar putea scădea considerabil fără referinţe în spate, deci fără

şiruri de caractere reţinute.

Referinţele ne permit să refolosim o parte din expresia regulată.

Cel mai auzit şi folosit scop este metoda de căutare şi înlocuire. Spreexemplu librăria PCRE nu dispune de o funcţie de căutare şi

 înlocuire.

Referinţele pot fi folosite nu numai după ce o potrivire destringuri este găsită (potrivire însemnând atunci când partea dinexpresia regulată găseşte un şir de caractere pe care se mulează) darşi în timpul căutării potrivirii. Să presupunem că vrem să preluăm untext şi tagurile aferente din html. Tagul de pornire este aproapeidentic cu tagul de terminare deci putem folosi primul tag ca

Page 23: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 23/42

referinţă pentru tagul de sfârşit. PCRE   permite, alături de .NET, Java

sau Perl, referinţe în faţă. Asta înseamnă că poţi folosi şirul decaractere rezultat şi memorat mai târziu în expresia regulată.Referinţele în faţă pot fi folositoare în situaţiile repetitive într-ungrup. Spre exemplu când scriem un şablon de alternare putem săavem ca alternative un şir normal şi un şir care este între paranteze

rotunde. Astfel şirul între paranteze rotunde atunci când este găsit caalternativă în şirul de caractere pe care-l căutăm va putea fi folosit

 înainte în verificarea alternativelor în aceeaşi paranteză rotundă. Ideeaeste că atunci când şirul dintre paranteze rotunde este returnat caalternativă se reţine ca referinţă în faţă tocmai şirul.

Un alt exemplu practic în care poate fi folosit conceptul de

referinţă este verificarea cuvintelor care apar de două ori. Parantezelerotunde   şi referinţele   de orice fel nu pot fi folosite în interiorul unei

clase de caractere. Ele pot fi folosite însă decât ca şi caractere literalenu ca şi meta-caractere   care ar avea vreo conotaţie speciale şi arputea fi interpretate. Spre exemplu clasa de caractere [x(y)]

alege între caracterele x,(,y şi ) nici vorbă de vreo paranteză rotundăcu referinţă. Referinţele în faţă sau în spate nu pot fi folosite nici ele

 într-o clasă de caractere căci vor fi interpretate în alte moduri decâtne-am aştepta noi. Aceste detalii trebuie ştiute ca atunci când leutilizăm să nu avem impresia că rezultatul nu este valid, ci doarcontextul în care l-am folosit nu ne favorizează. Cele mai simplemoduri de referinţă sunt $1,$2.. Spre exemplu referinţa $1 estesubşirul e caractere care reţine primul subpatern,$2 este al doilea şirde caractere şi aşa mai departe. Spre exemplu avem o alternare în

care avem pe rând răspunsurile a,b,c (ţinând cont că alternarea are şiun plus la sfârşit şi se poate repeta de o dată sau de mai multe ori).$1 o să fie a, $2 o să fie b şi aşa mai departe.

Motorul RegEx   va folosi ultimul şir de caracter drept referinţă oride câte ori este nevoie să-l folosească. Dacă este găsită o nouăpotrivire în paranteză în care se găseşte partea de expresie regulată

atunci referinţa se schimbă în aceea şi anume şirul de caractere pecare s-a făcut identificarea. De aici poate şi conceptul de referinţă, sereferă către ultimul subpattern   valid găsit. Să luăm un exemplupentru a clarifica lucrurile: avem următorul şablon ([xy]+)   şi

([xy])+ . La prima vedere nu pare prea mare diferenţă întrecele două, amândouă găsind şirul “yx”. Totuşi, primul şablon o săreţină ca referinţă şirul yx şi al doilea o să reţină şirul x. Primul

şablon este cu totul între paranteze. Astfel când verificăm yx, avempe y apoi pe x şi abia la sfârşit ieşim din parantezele deschise şireţinem ca referinţă pe yx. Pe când în al doilea şablon, când verificămpe yx avem y, care şi verifică o parte din string (însă backtrackingulmotorului RegEx   continuă) şi este reţinut ca referinţă şi apoi severificpă şi x, care este şi el reţinut ca referinţă şi adăugat lângă x.Toată treaba ţine de cum aranjăm parantezele rotunde şi de modul în

care se reţine referinţă. Totuşi trebuie să ţinem şi cont de faptul căodată ce mai multe referinţe sunt pe rând reţinute pe parcursulbacktrackingului motorului RegEx   timpul de căutare în interiorulşirului de caractere poate creşte considerabil, deci trebuie să avemgrijă cum folosim aceste paranteze rotunde şi referinţele şi sau dacăle folosim.

Page 24: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 24/42

Grupuri atomice, cuantificatori posesivi

Grupul atomic este acela, atunci când motorul RegEx   îşi termină şi îl părăseşte, automat el aruncă la o parte toate poziţiile din backtrack

reţinute. Mai pe scurt, odată ce a găsit o rezolvare validă el motorulRegEx, care ar trebui să ţină cont că ar mai putea fi şi alte rezolvări,părăseşte grupul atomic. Sintaxa pentru un grup atomic esteurmătoarea: (?>grup) . De reţinut că grupurile atomice suntsuportate în majoritatea motoarelor RegEx   şi anume:  Java, PCRE, .NET, Perl sau Ruby. Unele dintre ele suportă şi cuantificatori posesivipe care îi vom aminti un pic mai târziu.

Ca să înţelegem mai bine grupurile atomice  şi cum acesteafuncţionează defapt cel mai sănătos este un exemplu. Să considerămun şablon alternativ   de genul x(ab|a)b . Ştim că un astfel deşablon alternativ se mulează pe unul dintre celor două şiruri de textşi anume “xabb ” sau “xab “. Am scris sau deoarece odată ce unadintre variante este găsită în stringul de text căutat toată treaba se

 întrerupe. În cazul grupurilor atomice, exemplul de mai sus se vamula decât pe un singur string în orice caz şi anume xabb .Bineînţeles, pentru ca asta să se întâmple şablonul va arăta în felulurmător x(?>ab|a)b . Totuşi, poate părea ciudat, având unşablon alternativ ca unul dintre răspunsuri să nu se muleze niciodată.Atunci care ar mai fi scopul unui şablon alternativ? Ca să înţelegemscopul grupurilor atomice  şi rezultatul şablonului   de mai sus trebuie

 în primul rând să ştim cum funcţionează în acest caz motorul RegEx,motor despre care discutam la început. Să reluăm exemplu de maisus pas cu pas în cazul în care este un grup atomic. Să considerămşirul de caractere “xab “, care, în cazul în care nu este grup atomic arfi un răspuns valid. Motorul RegEx   intră şi verifică x cu x, găseşte şitrece mai departe. După aceea verifică primul şir de caractere dinşablon, şablon   care este într-un grup atomic, le găseşte şi trece mai

departe înafara alternării. Cum el nu mai îl găseşte şi pe b, fiind grupatomic   şi găsind o soluţie validă în interiorul alternării, părăseşteRegExul   şi nu se mulează pe şirul de caractere “xab “. Cu toate că,dacă grupul nu ar fi fost atomic, motorul RegEx nu s-ar fi oprit aicişi ar fi reţinut că mai are nişte valori de încercat în şablonul dealternare. Cam asta e treaba cu grupurile atomice, în mare.

Modul în care folosiţigrupurile atomice

 şi puterea pe care acesteapot sau nu să o aibă depinde doar de voi. Exemplul de mai sus esteunul minimal însă oricare dintre voi se poate juca într-un mod util cugrupurile atomice  dacă doreşte ca acestea să-l ajute într-un viitorproiect. Spre exemplu atunci când avem un şablon de alternare   cufoarte multe variante şi nu vrem să le încerce pe toate, dacă se

Page 25: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 25/42

poate, putem folosi grupuri atomice înauntrul şabloanelor dealternare. Însă dacă grupurile atomice  nu ne ajută şi dau răspunsurigreşite, mai bine nu le folosim în această situaţie. Este de reţinut căatunci când avem un şablon de alternare, pe măsură ce se verificăfiecare variantă în parte şi restul de date din afara alternării,backtrakingul folosit de motorul RegEx   are enorm de multe şiruri de

text de reţinut. Cu cât mai multe şiruri de text de reţinut şi cu câtmai multe încercări de făcut, cu atât mai mult timp de executat.

Acum să revenim la cuantificatori posesivi despre care începusemdiscuţia la început. Ca şi în cazul grupurilor atomice şi cuantificatoriiposesivi  au rolul de a micşora pe cât se poate numărul de încercărifăcute de motorul RegEx. Teoretic nu poate decât să fie un lucru bun

căci cu cât numărul de încercări din backtrackingul intern almotorului RegEx   este mai mic, cu atât timpul de execuţie este şi elmai mic. Un cuantificator   este un operator de repetiţie şi anume

* sau   + . Amândoi indică faptul că tot şirul de text careeste înainte se poate repeta. Ca să indicăm că un cuantificator esteposesiv   trebuie să îi adăugăm un plus +   în faţă în felul următor: ++,?+. Pentru a înţelege mai bine cu ce ne ajută un cuantificator posesiv

şi cum el poate influienţa numărul de iteraţii făcute, să luămurmătorul exemplu: fie şirul de caractere programator şi şablonulp[^b]*+r   Dacă îl analizăm ne dăm seama că şirul de caractereprogramator se mulează pe şablon căci *  ne spune că oricare caractercare nu este b poate să apară de ori de câte ori înainte de r. În cazul

 în care r-ul din şablon este eliminat, în cazul în care cuantificatorulnu este posesiv, acesta, odată cu insuccesul va încerca să caute şi

alte variante de răspuns valabile cum ar fi numai “programato” (careeste valabil, desigur, dar nu în cazul cuantificatorilor posesivi). Săpresupunem că noi avem nevoie neapărat de textul “programator”, iar

 în cazul în care acesta nu este găsit nu are sens să mai facem iteraţii în plus chiar dacă se mai găseşte prin textul iniţial un fragment. Înacest caz folosirea cuantificatorilor posesivi scuteşte motorul RegExde backtracking, nu neapărat inutil, cât nedorit de noi.

Faptul că aceşti cuantificatori posesivi  ne ajută ca expresiaregulată să fie verificată mai repede se bazează pe faptul că aceastăşi pică mult mai repede. După prima dată când nu se găseşte ceea cese caută totul este lăsat baltă şi se consideră că nu s-a găsit nimic.Trebuie ştiu şi faptul că aceşti cuantificatori posesivi nu sunt altcevadecât singularul de la grupurile atomice. Adică cuantificatorii posesivi

sunt o metodă convenţională de a pune grupuri atomice  lângă unsingur cuantificator. Deasemenea trebuie reţinut că motoarele RegExcare suportă cuantificatorii posesivi  suportă şi grupurile atomice  însănu toate motoarele RegEx   care suportă grupurile atomice suportă şicuantificatorii posesivi. Deci, pentru a nu întâmpina şi alte erori,atunci când se poate şi obţii exact aceleaşi rezultate poţi folosigrupurile atomice în loc de cuantificatorii posesivi. Oricum, alegerea

 îţi aparţine în funcţie de ceea ce vrei să obţii.

Page 26: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 26/42

Modificatori PCRE

Majoritatea expresiilor regulate   suportă modificatori. Modificatorii

permit schimbarea parametrilor   sub care se deşfăşoară căutarea în

stringul de caractere sau în fişiere. Modificatorii   oferă o mână deajutor programatorilor oferindu-le câteva opţiuni interesanteprecum(case-sensitive/case-insensitive set, single-line mode, multi-

line mode, free-spacing mode   sau modul fără lăcomie implicită aloperatorilor). Modificatorii sunt cei ce urmează mai jos:

/i   face motorul RegEx   insensitive. Adică nu va ţine cont

dacă sunt litere mari sau litere mici căci tot va returna acelaşirezultat valid. Spre exemplu avem şablonul: a(Ab|C)b   care va

returna valid şi pentru aAbb, acb şi aşa mai departe. Deci în acestcaz aAbb este acelaşi cu aaBB. Trebuie să fim atenţi atunci cândactivăm acest parametru şi pe ce porţiuni îl activăm, dacă îl activămpe porţiuni căci s-ar putea vizual să nu observăm că răspunsul chiareste unul valid şi nu eronat cum pare la început. Spre exemplu

şablonul x(Cz|a)G  o să returneze chiar şi următoarele şiruri decaractere: Xg, XcZG şi aşa mai departe.

/s   porneşte modul pe o singură line sau “single-line

mode“. În acest caz punctul indică şi spre \n. Faptul că punctul nuindică implicit către începuturi de linie şi anume \n este din motiveistorice. La început motoarele RegEx  erau folosite în modul text, pe o

singură linie şi era normal ca la sfârşit de linie să nu se găseascăniciodată indicele newline pentru linia următoare. Nu exista o linieurmătoare. Pe parcurs, odată ce lucrurile au evoluat şi odată cuacestea şi motoarele regex, a apărut posibilitatea de căutare pe maimulte rânduri deci şi indicele newline. Ca o întoarcele înapoi acumputem să reapelăm opţiunea single-lin mode pentru căutări pe osingură linie, spre exemplu.

/m   porneşte modul pe mai multe linii sau “multi-line

mode“. Desigur, în acest mod punctul nu indentifică newline-urile şidacă am vrea să o facă ar trebui să indicăm către modul single-linemode cu expresia /s . În modul multi-line-mode ^   şi

$  trebuie să identifice înainte şi după un indice de linie nouă şianume \n. Acest mod este modul implicit pe care este setat PCRE, de

exemplu. Acelaşi lucru se întâmplă şi la motorul RegEx de la Perl.

Dacă nu sunt caractere \n sau & şi $ în şirul vizat această opţiune nuare niciun efect atât la PCRE cât şi la Perl.

/x   indică modul “free-spacing mode” sau liber la spaţii. Înacest mod spaţiile libere sunt ignorate şi #   care nu sunt

Page 27: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 27/42

scapate indică un comentariu. Trebuie să fim atenţi odată activatăaceastă opţiune să nu ne dea bătăi e cap. În cazul în care expresiaregulată pe care ai scris-o este destul de complicată poţi includecomentarii pentru a fi mai uşor de înţeles de alţi programatori sauchiar de tine după o perioadă de timp.

/U   acest modificator   inversează lăcomia cuantificatorilor   casă nu mai fie lacomi implicit. În cazul în care e urmat de ?

devine lacom. Acesta nu este compatibil cu motorul RegEx de la Perl.

Trebuie menţionam că lăcomia provine din faptul că unii operatoriprecum * sau   +   nu se opresc la primul şir de caracterevalid dintr-o repetiţie ci încearcă şi celelalte şiruri de caractere, prinintermediul backtrackingului, poate, poate o mai fi vreunul valid. În

cazul în care se găsesc mai multe şiruri de caractere valide doarultimul dintre ele este returnat căci el este cel mai optim dintreşirurile de caractere prezente pentru alegere.

Mai sunt şi alţi câţiva modificatori   însă cei prezentaţi mai sus suntcei mai importanţi cu aplicaţii practice vizibile.

Există şi limbaje care nu suportă aceste opţiuni în RegEx cum ar fi JavaScript   şi Ruby. Desigur că fiecare limbaj poate avea implementatpe lângă opţiunile de bază şi altele.

Putem să indicăm o modificare  pe toată expresia regulată sau peanumite părţi din expresia regulată. Motoarele RegEx moderne ar

trebui să permită aplicarea de modificări şi pe porţiuni din expresia

regulată. Toata treaba a depins de cerere şi oferta de pe piaţă şinevoile programatorilor. Aşa cum la început totul stătatea în modultext şi nici că exista newline aşa acum se pot face foarte multelucruri interesante cu expresiile regulate   şi cu modificatorii. Dacăinserăm un modificator   în expresie acesta se va aplica tuturorcaracterelor acesteia de după modificator. Există posibilitatea ca la unmoment dat, după un anumit caracter să oprim modificarea. Spre

exemplu vrem ca unele caractere să fie case-sensitive şi altele nu.

Câteva aplicaţii practice   ale acestor modificatori ar putea fi

următoarele: să presupunem că vrem să scriem un cod minimal alunui motor de căutare în fişiere, după un anume algoritm propiu, şivrem să nu conteze dacă textul găsit este case-senzitive sau nu. Aiciputem să folosim modificatorul /i . Spre exemplu să

presupunem că un utilizator a creat un conţinut de genul:”Test teSt”,iar un alt utilizator, folosind motorul de căutare respectiv caută şirulde caractere „test test”. În acest caz, dacă nu folosim modificatorul

pentru case insenzitive o să observăm că nu vom găsi că cele douărezultate sunt identice deşi poate că, în contextul căutării şi primuluiconţinut scris de primul user, acestea două chiar sunt identice. Înacest caz modificatorii   sunt o soluţie eficientă pentru a rezolva o

problemă ciudată care ar putea apărea. O altă aplicaţie practicăpentru modificatori   ar fi transformarea în hexazecimal a unui codASCII, de exemplu. În cazul în care unii algoritmi de transformare lasăcâte un spaţiu sau două între 4 hexa şi vrem îi ignormă putem săfolosim /x   ca modificator pentru a elimina această problemădintr-o posibilă căutare. În cazul în care vrem să adăugăm comentariiputem să folosim cu încredere # . Aplicaţiile sunt nenumărate şi

depind doar de imaginaţia sau nevoile unui anumit programator la unmoment dat. Astea sunt doar două aplicaţii practice care mi-autrecut prin minte în acest moment.

 În concluzie modificatorii  sunt nişte opţiuni drăguţe care ne ajutasă facem o treabă mai eficientă cu expresiile regulate   şi adaugă un

Page 28: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 28/42

plus la acestea. Nu fac mare lucru, însă te pot ajuta la nevoie ca sănu te complici cu alte moduri mai complicate de şabloane  pentru

case insensitive, de exemplu.

Page 29: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 29/42

Sabloane alternative, PCRE

Clasele de caractere dintr-un şablon   pot indica un singur caracterdin mai multe caractere posibile. Totuşi, dacă vrem să indicăm mai

multe caractere dintr-un set de caractere? Sau o sintagmă (prinsintagmă înţelegem mai multe caractere) din mai multe sintagme?Cum clasele de caractere nu ne ajută în această situaţie putem folosiconceptul numit alternare. Conceptul de alternare tocmai astasemnifică: căutarea unei sintagme din mai multe sintagme posibile.Spre exemplu dacă vrem să căutăm textul literal programator saupisică putem face în felul următor folosind alternare

programator|pisică . Nu este neapărat o limitare la douăsintagme, lista poate să fie mai mare, gen:

programator|pisică|om|alternare .

Motorul RegEx   se va opri din căutat în momentul în care găseşteun rezultat valid, rezultat care se mulează corect pe şablonul   oferit.Trebuie să ţinem cont de acest lucru în momentul în care construim

şabloane folosind alternarea, nu care cumva să dorim o rezolvare şisă obţinem răspunsul la o altă problemă. Să luăm un exemplu, săpresupunem că vrem să căutăm sintagma programatoreficient întextul “programatoreficient pisică” şi scriem un şablon de genul:

pisică|programator|programatoreficient . S-ar putea caşablonul să nu găsească neapărat tot şirul programatoreficient, chiardacă acesta se găseşte în şablonul de alternare. Să vedem însă ce o

să găsească motorul RegEx. La început motorul RegEx   evalueazăexpresia regulată şi “observă” că în ea este un şablon de alternare. Lapasul următor se va verifica fiecare cuvânt din şablonul de alternarepână când unul se găseşte în şirul de text căutat. Cum cuvântulpisică nu se găseşte în textul în care căutăm, motorul RegEx va trecemai departe la cuvântul programator. Cuvântul programator va fireturnat căci el se găseşte în textul programatoreficient. Nu contează

că în şablonul de alternare se mai găseşte chiar şi şirul de caractereprogramatoreficient, căci procesul se opreşte. De ce se opreşte?Şablonul de alternare, analog cu clasele de caractere returneazănumai o sintagmă din sintagmele disponibile. Odată ce a găsit osintagmă care se găseşte în textul dat, ce rost mai are să caute oaltă sintagmă?

O altă aplicaţie practică a şabloanelor alternative poate să fieurmătoarea: filtrarea unor cuvinte dintr-o aplicaţie de chat. Săpresupunem că avem o listă de cuvinte care vrem să fim înlocuită.Nu este mai uşor să construim o expresie regulată   cu respectivelecuvinte iar în momentul în care sunt găsite acestea să fie înlocuite?Bineînţeles că treaba nu este chiar aşa de simplă pe cât pare însă cu

Page 30: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 30/42

puţină muncă putem să ajungem să ne punem în practică cu ajutorulexpresiilor regulate  orice ideea ne trece prin cap. Trebuie să fimatenţi la ordinea datelor din cadrul şabloanelor alternative dacă vremsă optimizăm treaba. Să presupunem că vrem să căutăm“numeprogramator” şi în şablonul alternativ avem următoarele date

(num|numepro|numeprogra|numeprogramator) . Este irelevant

să avem astfel de valori în şablonul de alternare căci în niciun caz nuvom găsi numeprogramator. Şirul de caractere „num” va fi găsit îninteriorul şirului de caractere iniţial “numeprogramator” şi cum esteun rezultat valid este şi returnat căci aşa functionează motorul RegEx.

 În acest caz trebuie să avem grijă ca cel mai mare şir de caracterecăutat să fie primul sau printre primele din şablonul de alternare căciastfel riscăm să nu ne alegem cu rezultatul dorit. Aşa se poate

 întâmpla şi în cazul în care avem următorul şablon:(test|pisică|mun|numeprogramator)  şi vrem să căutăm şirul

de caractere numeprogramator. Nu are sens ca acesta să fie tocmaila sfârşit căci până atunci motorul RegEx  şi aşa lucrează degeaba căcinu este posibil ca una dintre paternurile respective să fie valide. Cumabia ultimul patern este valid se observă că motorul RegEx a parcursşi a consumat timp degeaba şi programatorul ar fi putut evita acest

lucru adăugând pe prima sau pe primele poziţii şirurile de caracterede interes maxim, nu părţi din ele sau altele care nu au legătură cucăutarea. Contează deci şi ordinea şirurilor de caractere din şablonulde alternare pentru eficienţă sporită.

Şabloanele de alternare îşi găsesc exemple practic şi printregrupurile atomice  şi modul în care acestea pot fi optimizate pentru

un timp de execuţie al expresiei regulate mai mic. Să luăm următorulexemplu de şablon de alternare: \b(value|vla|vv)\b . Săobservăm analiza motorului RegEx   în cazul de faţă. Să presupunemcă avem şirul de caractere values pe care am dori să-l găsim şi vomdemonstra că prin intermediul şablonului de mai sus nu vom găsiceea ce ne aşteptăm, însă vom pierde un timp destul de mare laexecuţie să observăm acest lucru. \b   înseamnă începutul şirului

de caractere şi se potriveşte value cu value. Motorul RegEx   ţine contde faptul că mai sunt alternative   şi trece mai departe. Cele douăalternative   rămase nu sunt valide deci motorul RegEx iese dinşablonul de alternare. Observă că e-ul de la value nu este şi s-ul dela values, adică caracterul de sfârşit deci nici primul şir de caracteregăsit iniţial nu se potriveşte. Motorul RegEx a pierdut timpul degeabasă afle că nu există niciun şir de caractere care să se muleze pe şirul

pe care-l doream. Ca o mică optimizare ar trebui să îi spunem cumvamotorului RegEx   ca dacă atunci când nu reuşeste să îl găsească peprimul să nu se mai chinuie să le mai caute şi pe următoarele şiruri.

 În cazul unui grup atomic pe un şablon de alternare  motorul RegEx osă verifice primul şir de caractere apoi o să iasă din alternare ca săobserve dacă se potriveşe şi cu \b –ul de la sfârşit. Deoarece nuse potriveşte acesta va termina total execuţia. Diferenţa constă în

faptul că noi, ca programatori, ştiam că dacă primul nu este atunci numai are rost să continue şi am găsit o modalitate să optimizămalgoritmul. Totuşi, în alt context această modalitate s-ar putea să nuoptimizeze cât să ofere rezultate eronate sau neaşteptate. De aceeatrebuie să lucrăm cu grijă cu şabloanele alternative şi cu eventualelegrupuri atomice sau alte expresii regulate   ataşate pe ele. Să nucumva să avem în minte o chestie şi să obţinem altă chestie.

Page 31: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 31/42

Unicode in PCRE

Unicode  încearcă să înglobeze caractere şi simboluri din mai toatelimbile pământului. Prin intermediul şablonului Unicode putem să

avem la un loc sisteme de scriere pentru toate limbile planetei şipentru cele care nu mai există. În ziua de azi cum toată lumeadoreşte să aibă o versiune în limba propie sau în câteva limbi maicunoscute, Unicode  a început să joace un rol deosebit de important.Astfel utilizatorii pot să definească în programele lor caractere sausimboluri diverse. Asta înseamnă că şi motorul RegEx  trebuie să fie înpas cu aceasta. Java, XML şi .Net folosec motoare RegEx   care au deja

inclus Unicode. PCRE nu vine cu Unicode  inclus însă poate să fiecompilat şi cu suport pentru Unicode. Acum vine partea drăguţăpentru programatorii care utilizează motorul RegEx şi Unicodurile .

Cred că a auzit toată lumea de caracterele cu accent deasupra. Chiardacă literal se numeşte caracter, din punct de vedere Unicode s-ar

putea ca un altfel de caracter să nu fie doar unul singur. Unicode

foloseşte noţiunea de ‘code point‘ şi, spre exemplu, caracterele cu

accent sunt o sumă de două code pointuri. Asta implică o situaţiedestul de dubioasă şi poate într-un fel încurca treburile de pânăacum ale expresiilor regulate. Spre exemplu punctul identifică oricecaracter sau, pentru Unicode, orice codepoint. Deci dacă el identificăorice code point   înseamnă că nu va identifica şi aşa zisul caracter cuaccent căci acesta este o sumă de două code pointuri . Nu ar fi

problema aşa de mare căci nu toate Unicodurile sunt formate din mai

multe code pointuri   şi dacă sunt formate au şi varianta de un singurcode point.

Ştim acum că punctul indică spre un singur caracter sau către unsingur code point   însă în cazul în care un caracter este format dinmai multe code pointuri, în Unicode, atunci punctul nu-şi treaba.Dacă PCRE este compilat cu librăria pentru Unicode atunci putem să

folosim \X , versiunea Unicode pentru punctul din motorulRegEx. Cam singura diferenţă care ar fi între punct şi \X   este

că \X   indică şi spre \n   pe când punctul nu o face înmodul implicit. Punctul foloseşte ASCII şi \x   foloseşte Unicode

pentru a găsi caracterele căutate. Pentru a indica către un singur code

point sau Unicode  putem folosi următoarul şablon: \x{FFFF} .

Acest tip de şablon este folosit şi de Perl pe când, spre exemplu,

 Javascript foloseşte un alt mod de verificare Unicode  şi anume:\uFFFF . Acest tip de căutare va indica către code pointul dinUnicode U+FFFF. Dacă vrem să căutăm code pointul de mai multe ori

la rând putem să folosim următorul şablon:\x{FFFF}{număr_de_ori} . Spuneam că Unicode include foarte

multe caractere din mai toate limbile cât şi simboluri. Înafară de

Page 32: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 32/42

complicaţii Unicode-ul aduce şi multe lucruri interesante precumposibilitatea de a integra un caracter într-o anumită categorie. Ca săfacem acest lucru putem să folosim şablonul următor: \p{}   şica să nu aparţină unei categorii folosim şablonul: \P{} . Spre

exemplu dacă vrem să indicăm doar spre caracterele (şi prin caracterne referim tot la code pointuri Unicode) din categoria literă avem

următorul şablon: \p{L}   , dacă vrem să ne referim la toatecode pointurile înafară de cele din categoria literă avem şablonul:

\P{L} . PCRE   este case sensitive şi trebuie să avem grijă cândspecificăm o anumită categorie cu litere mici şi când cu litere mari.Există şi scurturi şi spre exemplu PCRE, alături de Perl şi Java neacordă posibilitatea să le folosim şi anume că în loc de

\p{literă_categorie sau litere_categorie}   se poate

folosi \pliteră_categorie . Pentru categoria litere vom avea:\pL . Mai există câteva categorii şi anume: M ( pentru accente,

umlauts), S (pentru simboluri, simboluri matematice), N (orice tip denumăr), P (semne de punctuaţie).

Există şi aşa numitele scripturi Unicode. Un script este un grup de

code pointuri   folosite de o naţiune pentru sistemul de scriere. Având

acest script ne este mai uşor să identificăm doar code pointurilepentru o anumită limbă sau să verificăm dacă un text este scris într-o limbă, folosind code pointurile limbile respective, sau în alta. Unele

limbi sunt compuse din mai multe scripturi Unicode  căci au nevoie demai multe caractere şi simboluri cum e limba japoneză. Ca săverificăm code pointurile   dintr-un anumit script putem să folosimurmătorul şablon: \p{sistem_de_scriere} , exemplu:

p\{Latin}  pentru sistemul de scriere din latină.

Există şi aşa numitele blocuri Unicode. Blocurile sunt o categorie

continuă de code pointuri   pe când scripturile Unicode  nu necesităneapărat acest lucru. Blocurile pot să conţină şi code pointuri care

 încă nu sunt asignate şi probabil că vor fi pe viitor. Şabloanele   se

scriu tot ca la scripturi Unicode, ca în exemplul următor:

\p{InLatin_Extended-B} . Acestea pot fi însă folosite de Perl, Java, .NET sau XML căci PCRE nu suportă blocuri Unicode.

Spre exemplu în PCRE   pentru a nega o anumită categorie putemsă folosim şablonul: \p{^L}   însă şi şablonul următor estecorect: \P{L} . Cel mai bine de folosit pentru a nega o clasăeste să folosim ultimul şablon de mai sus \P{L}   căci

majoritatea motoarelor RegEx   folosesc această notaţie. PCRE şi Perlsunt printre singurele care permit şi notaţia: \p{^L} . Dacăvrem ca şi alţi programatori să înţeleagă şi să nu apară erori dedescifrare a şablonului este cel mai bine să folosim standardulgeneral care este folosit în majoritatea motoarelor RegEx pentru

denumire şi negare de categorii Unicode. Se pare că Unicode, în ciuda

faptului că poate oferi şi câteva complicaţii de înţelegere, oferă şi

multe avantaje majore. Oricum, complicaţiile de înţelegere suntdevastate net de avantajele code pointurilor Unicode. Totul depinde

de contextul în care viitorul programator abordează o anumităproblemă şi necesităţile sale în momentul respectiv. Trebuie săreţinem faptul că PCRE nu vine implicit cu suportul pentru caractere

Unicode  şi ca pentru aceasta trebuie compilat cu acest suport dacăavem nevoie. În cazul în care este compilat cu acest suport face

posibilă utilizarea secvenţelor de scăpare \p{..} , \P{..}şi \X , descrise deja mai sus. O chestie care nu este suportatăde PCRE  sunt propietăţile prefixate de “Is”. Acestea sunt folosite, spreexemplu, în Perl dar nu şi în PCRE.

Page 33: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 33/42

Expresii regulate

RegEx in Perl

Perl este un limbaj de programare creat de Lary Wall in 1987

având ca principal cop procesarea şi manipularea de text, dupa cum

 îi spune si numele – Practical Extraction and Report Language.Principalul motiv pentru care Perl  a ajuns sa aibă succesul actual esteimplementarea expresiilor regulate   într-un mod care oferă oflexibilitate foarte mare şi în acelaşi timp o uşurinţă în utilizare.Putem spune fără să exagerăm că expresiile regulate sunt cele care

au adus Perl la nivelul la care este acum.

Pentru lucrul cu expresiile regulate Perl   pune la dispoziţie maimulţi operatori care faciliteaza căutarea şi substituţia textelor.Operatorii cel mai des întâlniţi sunt m// , s///   si

qr// , operatori despre care vom vorbi în rândurile de mai jos.

Operatorul m//   este folosit pentru căutarea în cadrultextelor pe baza unui şablon specificat între cele două caractere slash

( / ). Textul de procesat este “pasat” operatorului m// prinintermediul operatorilor =~ şi !~. În cazul în care se găseşte opotrivire de şablon, operatorul m// returnează “true”, motiv pentrucare poate fi folosit direct în cadrul instrucţiunilor de control. Unexemplu de utilizare ar fi urmatorul:

La rulare scriptul va trebui sa afişeze pe ecran urmatorul mesaj:Am gasit cuvantul “Perl” in text. Trebuie mentionat ca Perl   foloseşteoperatorul m//   ca operator implicit. Astfel operatorul poate

lipsi, efectul fiind acelaşi. Deci, dacă înlocuim m/Perl/   cu

/Perl/   (observaţi lipsa literei m) expresia va fi valabilă încontinuare şi va returna adevărat dacă se găseşte o potrivire de

şablon.

Dacă am avea un text mai mare iar cuvantul Perl ar fi scris cu

literă mică ar trebui sa facem o regula mai mare, folosind şabloanealternative, cum ar fi perl|Perl . Totuşi, dacă e un textcomplex s-ar putea ca Perl să fie scris ca PERL sau PeRl sau PerL

1

2

34

5

6

7

8

#!/usr/bin/perl

my  $t ext   =  ' Expr esi i l e regul at e au f acut l i mbaj ulPer l put er ni c. ' ;

  $t ext   . =  ' Per l est e un l i mbaj f l exi bi l . ' ;

i f (   $t ext =~  m/Perl/   )   {

  pr i nt   "Am gasi t cuvant ul \"Per l  \"  i n t ext .  \n" ;

}

Page 34: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 34/42

astfel formându-se un şablon foarte lung şi greu de urmărit. În cazuride genul acesta putem folosi operatorul i   pus la sfârşit,operator care ii spune motorului RegEx   că şablonul folosit e case-insensitive, adică nu va face diferenţă între literele mici şi cele mari.

Folosind operatorul i , exemplul de mai sus va deveni:

Observaţi modificările, şi anume lipsa operatorului m   care e

implicit, şablonul   care e cuvântul perl   scris cu litere mici şioperatorul i de la sfârşit care determină tratarea şablonului în mod

case-insensitive. După cum bănuiţi, la rulare va fi afişat acelaşi mesajchiar dacă şablonul este scris cu litere mici.

Bun, acum să mergem puţin mai departe la operatorul s/// ,operator folosit pentru înlocuiri. Utilizarea acestuia este asemănătoarecu cea a operatorului de căutare, cu menţiunea că oriunde găseşte opotrivire a şablonului dintre primele două caractere slash ( / ) va

 înlocui rezultatul cu şirul specificat între al doilea şi al treilea slash.Un exemplu ar fi următorul:

Rezultatul va fi următorul:

Expresiile regulate au facut limbajul PERL puternic. Perl este un 

limbaj flexibil.

După cum vedeţi textul a fost înlocuit. Totuşi se poate observa omică problema şi anume faptul că operatorul s//   a înlocuit

doar primul Perl întâlnit. O soluţie de rezolvare a acestei situaţii ar fisă folosim o buclă while care să înlocuiască Perl cu PERL iar apoi sărecitească textul şi să aplice şablonul. Chiar daca nu ar lua decât

doua linii de cod în plus nu este o soluţie bună din punct de vedereal resurselor consumate – care vor fi foarte multe daca aveţi de-aface cu texte mari şi multe. O soluţie elegantă ar fi să folosimoperatorul g , care ii va spune motorului RegEx   să caute toatepotrivirile pe şablonul dat iar apoi să le înlocuiască. Astfel, codul demai sus se transformă în:

1

2

3

4

5

6

7

8

#!/usr/bin/perl

my  $t ext   =  ' Expr esi i l e regul at e au f acut l i mbaj ul

Per l put er ni c. ' ;

  $t ext   . =  ' Per l est e un l i mbaj f l exi bi l . ' ;

i f (   $t ext =~  /perl/i  )   {

  pr i nt   "Am gasi t cuvant ul \"Per l  \"  i n t ext .  \n" ;

}

1

2

3

4

5

67

#!/usr/bin/perl

my  $t ext   =  ' Expr esi i l e regul at e au f acut l i mbaj ul

Per l put er ni c. ' ;

  $t ext   . =  ' Per l est e un l i mbaj f l exi bi l . ' ;

$t ext =~  s/Perl/PERL/ ;

pr i nt   "$t ext \n" ;

12

3

4

5

6

#!/usr/bin/perl

my  $t ext   =  ' Expr esi i l e regul at e au f acut l i mbaj ul

Per l put er ni c. ' ;

  $t ext   . =  ' Per l est e un l i mbaj f l exi bi l . ' ;

Page 35: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 35/42

Iar rezultatul va fi:

Expresiile regulate au facut limbajul PERL puternic. PERL este un 

limbaj flexibil.

Dacă ar fi cazul am putea adăuga şi operatorul i   pentru ca

şablonul sa nu facă diferenţa între literele mici şi literele mari.

Pentru a forma şabloane complexe   Perl   foloseşte clase de

caractere şi cuantificatori. Cu ajutorul claselor de caractere putem

forma foarte uşor un şablon cu ajutorul căruia sa detectăm daca oadresă e-mail este validă sau nu, sau putem verifica daca un şir

trimis are se încadrează ca lungime în limitele impuse. Mai jos aveţi olista de clase de caractere şi cuantificatori folosiţi în Perl.

.  Face potrivire pe orice caracter.

\w  Face potrivire pe orice caracter folosit într-un cuvânt – caractere

alfanumerice şi semnul underscore (_)\W  Face potrivire pe orice caracter care nu e folosit într-un cuvânt –

opusul clasei \w

\s  Face potrivire pe orice spaţiu\S  Face potrivire pe orice caracter care nu e spaţiu\d  Face potrivire pe orice cifră\D  Face potrivire pe orice caracter care nu e cifră\024   Face potrivire pe orice caracter scris în mod octal – în

cazul nostru caracterul 24

\xcc  Face potrivire pe orice caracter scris in hexazecimal – în cazul

nostru cc

* Caracterul anterior sau clasa anterioară se repeta de zerosau mai multe ori

+  Caracterul anterior sau clasa anterioară se repeta cel puţin odată

?   Caracterul anterior sau clasa anterioară se repeta o dată sau

deloc{n}   Caracterul anterior sau clasa anterioară se repeta de fix n

ori

{n,}   Caracterul anterior sau clasa anterioară se repeta de celpuţin n ori

{n,m}  Caracterul anterior sau clasa anterioară se repeta de cel puţinn ori şi cel mult m ori.

Pentru cazul în care avem de verificat o potrivire din care ne

interesează doar o anumită parte putem folosi gruparea elementelor

din şablon   folosind parantezele rotunde. Fiecare set de paranteze

rotunde e considerat un grup iar după ce se face potrivirea rezultatulva putea fi regăsit într-un set de variabile speciale sub formă denumere. Astfel, primul grup va fi $1, al doilea $2, al treilea $3 etc.

Pentru o mai bună înţelegere, urmăriţi exemplul de mai jos:

La rulare vom citi pe ecran textul: Am extras: 1987 .

Pe scurt, acesta e modul de funcţionare a expresiilor regulate în

7 t ext =~  s/Perl/PERL/g ;

pr i nt   "$t ext  \n" ;

1

2

3

4

5

6

#!/usr/bin/perl

my  $t ext   =  ' Li mbaj ul Per l a f ost cr eat i n anul

1987. ' ;

$t ext =~  /anul (\d+)/ ;

pr i nt   "Am ext r as: $1.  \n" ;

Page 36: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 36/42

Perl. Exemplele oferite vă vor ajuta să puneţi în practică expresiile

regulate folosind limbajul Perl. Dacă aveţi nevoie de mai mult vărecomand să citiţi pagina de manual a expresiilor regulate în Perl.

Page 37: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 37/42

RegEx in JavasScript

Incepand cu JavaScript v1.2 limbajul suporta expresiile regulate

folosind o sintaxa asemanatoare cu sintaxa Perl. Folosind expresiile

regulate in JavaScript, in contextul Web 2.0 unde totul se rezuma lautilizator si la dorinta acestuia de a crea continut, munca

programatorului devine mai usoara scutindu-l de multe linii de cod

care cu functii alternative de parsare a textului ar consuma mai mult

din timpul programatorului si mai multe resurse pe sistemul client.

In JavaScript expresiile regulate pot fi folosite in doua moduri:

folosind caracterele slash /expresie/modificator  sau folosindconstructorul RegExp(“expresie”, “modificator”) . Ambele

moduri sunt utile, de obicei diferenta facandu-se la stilul de codare

al programatorului. O diferenta mare se poate observa totusi la

modul in care se formeaza expresiile regulate. Folosind constructorul

RegExp va trebui sa insotim fiecare caracter special de un backslash.

Astfel, in timp ce un sir care nu contine cifre va fi reprezentat in

prima varianta prin /\D+/g , in varianta cu constructorul vom finevoiti sa adaugam un backslash inainte caracterului backslash care

va determina clasa de caractere folosita: RegEx(“\\D+”, “g”) .

Indiferent de varianta aleasa, putem aplica doua functii pe sirurile

testate. Prima este test() , cu ajutorul careia putem verifica

daca sablonul creat se potriveste pe text. A doua este exec() ,

cu ajutorul careia putem extrage informatii folosind expresiileregulate. Mai jos avem cate un exemplu din fiecare situatie:

Sau in varianta in care folosim constructorul RegExp() :

Observati ca in cazul constructorului am inlocuit \d+   cu

\\d+   – de doua ori caracterul backslash pentru ca expresia

regulata sa se formeze corect.

In mod similar putem folosi exec()   pentru a extrage din

sirul dat spre procesare partea din text care ne intereseaza:

var re = /\d+/ ;

if( re.test("test1234") ) window.alert('Match!');

else window.alert('No match!');

var re = new RegExp("\\d+");

if( re.test("test1234") ) window.alert('Match!');

else window.alert('No match!');

re = /\D+(\d+)\D+/ ;

Page 38: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 38/42

In mod similar se poate folosi si varianta constructorului

RegExp()   cu conditia sa adaugam un backslash in fata

caracterelor speciale.

In exemplul de mai sus am folosit sablonul /\D+(\d+)\D+/

care cauta un sir de cifre inconjurat de un sir de orice alte caractere

care nu sunt cifre. Putem observa ca variabila “i” care am folosit-o

pentru incrementare porneste de la 1 in cadrul buclei for si asta

pentru ca primul element din array-ul returnat de functia

exec()   este textul in care s-a gasit potrivirea, nu doar

potrivirea care o cautam.

Pentru a extinde functionalitatile expresiilor regulate in JavaScript,

obiectele de tip String   din JavaScript au de asemenea implementate

functii care folosesc sabloane. Aceste functii sunt

String.match(“sablon”)   pentru identificarea unui subsir care

se potriveste sablonului in cadrul unui sir de caractere mai mare,

String.search(“sablon”)   pentru a returna indexul primului

caracter la care se gaseste potrivirea sau -1 in cazul in care

potrivirea sablonului nu a fost posibila,

String.replace(“sablon”, “text”)   pentru a inlocui sirurile

de caractere care corespund sablonului cu un text dat si

String.split(“sablon”)   pentru a transforma un sir de

caractere intr-un array separand elementele sirului in functie de

sablonul dat.

el = re.exec("test23test");

if( el.length > 0 )

  for( i=1; i<el .length; i++ )

  document.write(i + ": " + el[i] + "<br />");

else document.write("No match!");

Page 39: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 39/42

Exemple de expresii regulate PCRE

Sa vedem cateva exemple practice, snippeturi, in care putem folosi

expresiile regulate. Sintaxa folosita va fi PCRE.

Numerele intregi pozitive pot fi privite ca un sir lung format doar

din cifre:

^\d+$ .

Numerele intregi negative, spre deosebire de cele pozitive, sunt

prefixate de un semn minus:

^-\d+$ .

Numerele intregi in general, fara a face diferenta intre cele

pozitive si cele negative, sunt formate dintr-un sir de cifre prefixate

de 0 sau 1 semne minus:

^-{0,1}\d+$ .

Numerele reale pozitive pot fi vazute ca fiind formate din 0 sau

mai multe cifre urmate de 0 sau 1 puncte (se poate inlocui cu virgulapentru zecimale) dupa care urmeaza din nou un set de cifre:

^\d*\.{0,1}\d+$ .

Numerele reale negative sunt declarate la fel ca cele pozitive cu

diferenta ca sunt prefixate de semnul minus:

^-\d*\.{0,1}\d+$ .

Numerele reale in general, fara a face diferenta dintre cele pozitive

si cele negative, pot fi gasite adaugand in sablon posibilitatea

existentei a 0 sau 1 semne minus:

^-{0,1}\d*\.{0,1}\d+$ .

Numerele de telefon pot fi vazute ca o serie de minim 3 cifre

(numere scurte) care pot fi prefixate de semnul plus:^\+?[\d\s]{3,}$ .

Anii ii putem potrivi in sablon ca fiind siruri de cifre din care

primele doua sunt 19 sau 20 dupa care urmeaza inca fix doua cifre:

^(19|20)[\d]{2,2}$ .

IP-urile (IPv4) pot fi vazute ca 4 grupuri de cifre separate depuncte. Pentru a ne asigura ca valorile fiecaruia din cele 4 grupuri nu

depasesc 255 trebuie create mai multe cazuri folosind operatorul OR

(|):

^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-

9]\d|1\d\d|2[0-4]\d|25[0-5]){3}$

Page 40: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 40/42

Pentru validarea unei adrese e-mail avem cifre, litere si cateva

semne speciale (._%+-) urmate de @ dupa care urmeaza numele

domeniului si TLD-ul:

^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ .

Numele domeniului e format din cifre, litere si semnele punct (.)pentru subdomenii sau domeniile cu SLD si semnul minus (-), dupa

care urmeaza de la doua la 4 litere TLD-ul:

^[A-Z0-9.-]+\.[A-Z]{2,4}$ .

Pentru a verifica inexistenta unei valori avem semnul de inceput si

cel de sfarsit de sablon fara nici un alt caracter intre ele:

^$ .

Pentru verificarea spatiilor albe, verificam spatiile simple (tasta

space) si caracterele TAB:

^\s[\t]*$ .

Verificarea finalizarii randului indiferent de sistemul de operare se

face cautand \r (UNIX) \r\n (Windows):[\r\n]$ .

Posted in Fără categorie | Comentarii oprite

Comments are closed.

Page 41: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 41/42

Exemple de expresii regulate PCRE

Sa vedem cateva exemple practice, snippeturi, in care putem folosi

expresiile regulate. Sintaxa folosita va fi PCRE.

Numerele intregi pozitive pot fi privite ca un sir lung format doar

din cifre:

^\d+$ .

Numerele intregi negative, spre deosebire de cele pozitive, sunt

prefixate de un semn minus:

^-\d+$ .

Numerele intregi in general, fara a face diferenta intre cele

pozitive si cele negative, sunt formate dintr-un sir de cifre prefixate

de 0 sau 1 semne minus:

^-{0,1}\d+$ .

Numerele reale pozitive pot fi vazute ca fiind formate din 0 sau

mai multe cifre urmate de 0 sau 1 puncte (se poate inlocui cu virgulapentru zecimale) dupa care urmeaza din nou un set de cifre:

^\d*\.{0,1}\d+$ .

Numerele reale negative sunt declarate la fel ca cele pozitive cu

diferenta ca sunt prefixate de semnul minus:

^-\d*\.{0,1}\d+$ .

Numerele reale in general, fara a face diferenta dintre cele pozitive

si cele negative, pot fi gasite adaugand in sablon posibilitatea

existentei a 0 sau 1 semne minus:

^-{0,1}\d*\.{0,1}\d+$ .

Numerele de telefon pot fi vazute ca o serie de minim 3 cifre

(numere scurte) care pot fi prefixate de semnul plus:^\+?[\d\s]{3,}$ .

Anii ii putem potrivi in sablon ca fiind siruri de cifre din care

primele doua sunt 19 sau 20 dupa care urmeaza inca fix doua cifre:

^(19|20)[\d]{2,2}$ .

IP-urile (IPv4) pot fi vazute ca 4 grupuri de cifre separate depuncte. Pentru a ne asigura ca valorile fiecaruia din cele 4 grupuri nu

depasesc 255 trebuie create mai multe cazuri folosind operatorul OR

(|):

^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-

9]\d|1\d\d|2[0-4]\d|25[0-5]){3}$

Page 42: RegEx - Expresii Regulate

7/23/2019 RegEx - Expresii Regulate

http://slidepdf.com/reader/full/regex-expresii-regulate 42/42

Pentru validarea unei adrese e-mail avem cifre, litere si cateva

semne speciale (._%+-) urmate de @ dupa care urmeaza numele

domeniului si TLD-ul:

^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$ .

Numele domeniului e format din cifre, litere si semnele punct (.)pentru subdomenii sau domeniile cu SLD si semnul minus (-), dupa

care urmeaza de la doua la 4 litere TLD-ul:

^[A-Z0-9.-]+\.[A-Z]{2,4}$ .

Pentru a verifica inexistenta unei valori avem semnul de inceput si

cel de sfarsit de sablon fara nici un alt caracter intre ele:

^$ .

Pentru verificarea spatiilor albe, verificam spatiile simple (tasta

space) si caracterele TAB:

^\s[\t]*$ .

Verificarea finalizarii randului indiferent de sistemul de operare se

face cautand \r (UNIX) \r\n (Windows):[\r\n]$ .

Posted in Fără categorie | Comentarii oprite