Expresii regulate  


Cãutare


Siteuri recomandate

  • ABC Domenii Pachete de gazduire pentru siteuri personale si bloguri.
  • AutoIt Script Curs AutoIt in limba romana.
  • CHML Web Services Servere dedicate si servere virtuale private.
  • Hostvision Gazduire siteuri web si inregistrare domenii
  • IPFind.eu IPFind.eu – Free IP address finder and DNS troubleshooter
  • LAMP Platforma open source de gazduire a site-urilor web.
  • NetHelp Intrebari tehnice si raspunsuri de calitate pentru intrebari tehnice.
  • SkullBox Comunitate online pentru pasionatii de IT.
  • WordPress Admin Tutoriale de utilizare si administrare a blogurilor WordPress.

Grupuri si referinte PCRE

Dacă vrei să grupezi părţi din expresia regulată o poţi face punâ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ţi din expresia regulată. Restul de paranteze au alte funcţii şi nu pot fi folosite la grupare.

Înafară de gruparea unei părţi din expresia regulată, parantezele rotunde crează şi o referinţă înapoi. O referinţă înapoi reţine partea din şirul de caractere care se mulează pe partea din expresia regulată din paranteză. Această operaţie bineînţeles că face ca toată treaba motorului RegEx să se desfăşoare mai lent căci sunt mai multe lucruri 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 de partea de expresie regulată dintre paranteze şi în acest fel se poate mări viteze de execuţie. Ca să înţelegem mai bine mecanismul şi modul în care funcţionează gruparea şi referinţele o să luăm un exemplu: fie expresia regulată programator(bun)? . Aceasta se mulează pe două şiruri de caractere şi anume programator sau programatorbun căci ? înseamnă că subexpresia sau caracterul de dinainte se poate repeta o dată sau niciodată. Gruparea unei părţi din expresia regulată, chiar şi o subexpresie la modul literal o să reţină şirul de caractere de dinainte, interpretat. În primul caz şirul nu există căci se returnează doar programator însă în al doilea caz acesta există şi este bun, chiar şirul de caractere literal. Putem deci să nu folosim referinţe şi să nu se mai reţină şirul de caractere bun pentru a micşora timpul de execuţie. Bineînţeles că exemplul nu este complex, totuşi la şiruri de caractere mari sau la fişiere timpul de execuţ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. Spre exemplu 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 de stringuri este găsită (potrivire însemnând atunci când partea din expresia 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 un text şi tagurile aferente din html. Tagul de pornire este aproape identic cu tagul de terminare deci putem folosi primul tag ca 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 de caractere rezultat şi memorat mai târziu în expresia regulată. Referinţele în faţă pot fi folositoare în situaţiile repetitive într-un grup. 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 ca alternativă în şirul de caractere pe care-l căutăm va putea fi folosit înainte în verificarea alternativelor în aceeaşi paranteză rotundă. Ideea este că atunci când şirul dintre paranteze rotunde este returnat ca alternativă 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. Parantezele rotunde ş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 literale nu ca şi meta-caractere care ar avea vreo conotaţie speciale şi ar putea 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ât ne-am aştepta noi. Aceste detalii trebuie ştiute ca atunci când le utilizăm să nu avem impresia că rezultatul nu este valid, ci doar contextul în care l-am folosit nu ne favorizează. Cele mai simple moduri de referinţă sunt $1,$2.. Spre exemplu referinţa $1 este subşirul e caractere care reţine primul subpatern,$2 este al doilea şir de 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 şi un 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ţă ori de 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 pe care s-a făcut identificarea. De aici poate şi conceptul de referinţă, se referă către ultimul subpattern valid găsit. Să luăm un exemplu pentru a clarifica lucrurile: avem următorul şablon ([xy]+) şi ([xy])+. La prima vedere nu pare prea mare diferenţă între cele 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, avem pe y apoi pe x şi abia la sfârşit ieşim din parantezele deschise şi reţinem ca referinţă pe yx. Pe când în al doilea şablon, când verificăm pe yx avem y, care şi verifică o parte din string (însă backtrackingul motorului RegEx continuă) şi este reţinut ca referinţă şi apoi se verificpă ş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 parcursul backtrackingului motorului RegEx timpul de căutare în interiorul şirului de caractere poate creşte considerabil, deci trebuie să avem grijă cum folosim aceste paranteze rotunde şi referinţele şi sau dacă le folosim.