Expresii regulate în limbajul PHP

Introducere modificare

Căutarea și identificarea anumitor secvențe într-un text a fost, este și va fi o problemă foarte importantă în informatică. Acest articol se va opri doar asupra problemelor de căutare utilizand expresii regulate compatibile Perl în limbajul de programare PHP.

O expresie regulată este o secvența de caractere cu rol de șablon (pattern). Acest sablon se aplica peste un subiect (un sir de caractere) pentru a extrage toate subsirurile care au aceeasi structura cu sablonul definit.

Exemplu:

[0-9]+ - orice insiruire de cifre - fiind aplicat peste sirul 12as323n2131nnk$#,m23&*K va extrage: 12, 323, 2131, 23

PHP este capabil sa interpreteze 2 standarde: PCRE si POSIX. In cele ce urmeaza prezentam doar standardul PCRE - Perl-compatible Regular Expressions.

Caractere speciale modificare

  • ^ - indicator inceput de subiect/linie
  • $ - indicator sfarsit de subiect/linie
  • * - caracterul anterior, repetat de oricate ori (>=0)
  • . - orice caracter cu exceptia new-line
  • [ ] - un caracter dintre cele din lista
  • [ ^ ] - orice caracter cu exceptia celor din lista
  • \ - scoate din contextul uzual caracterul care urmeaza
  • + - caracterul anterior, repetat cel putin o data (>0)
  • ? - caracterul anterior, cel mult o aparitie
  • < > - un cuvant intreg
  • ( | ) - lista de optiuni (SAU)
  • ( ) - subpattern
  • { } repetarea unui caracter de un numar precizat de ori
  • \d - [0-9]
  • \D - [^0-9]
  • \s - spatiu
  • \S - non-spatiu
  • \w - [a-zA-Z0-9_]
  • \W - [^a-zA-Z0-9_]

Exemple modificare

  • 't[a-i]c' -> tac, tic, tbc, ...
  • 'cr[a-m]*t' -> credit, croit, crit, ...
  • 'ca.*a' -> cana, cabana, ...
  • '(co|ca).*c' -> copac, conac, capac, cazac...
  • 's[aeiou]*c'-> sac, sic, sc...
  • 'm[^a-c]*t' -> moft, mut, mosit...
  • 's[a-z]{2,3}t' -> soft, sarat, sosit, ...

Expresii Regulate in PHP modificare

Pentru a fi capabil sa lucreze cu PCRE, PHP trebuie sa fi fost compilat cu --with-pcre-regex

PCRE fiind o librarie externa, conteaza foarte mult si versiune ce o avem instalata pe sistem, existand diferente atat de sintaxa cat si de performanta de la o versiunea la alta.

O expresie regulata trebuie inclusa intre delimitatori. De exemplu, in aceasta prezentare, folosim ' / ' pe post de delimitator, nefiind un caracter special, dar care trebuie trebuie scos din contextul uzual in momentul în care il folosim in interiorul expresiei.

Exemplu: /[a-z]+/i

Modificatori de pattern modificare

  • i - pattern-ul nu este tratat case-insensitive
  • m - trecerea la modul multiline
  • s - Permite caracterului special . sa interpreteze si newline. Chiar si fara acest modificator, ^ va considera valid caracterul newline
  • x - ignora spatiile si si tot ce e cuprins intre # si newline
  • e - folosit doar de preg-replace() pentru a interpreta \ la fel ca in codul PHP
  • A - folosit pentru interpretare doar la inceputul subiectului
  • D - folosit pentru a interpreta $ doar ca sfarsit de subiect. Este ignorat insa in modul multiline

Setul de functii PHP modificare

preg_grep — Returneaza un vector cu rezultatele interpretarii

preg_last_error — Returneaza codul de eroare al ultimei expresii regulate executate

preg_match_all — Cauta in subiect toate interpretarile expresiei regulate si returneaza un vector cu rezultatele gasite.

preg_match — Cauta in subiect prima potrivire a expresiei regulate

preg_quote — Scoate din context caracterele speciale

preg_replace_callback — Aplica o functie de tip callback peste rezultatul un cautari si inlocuiri

preg_replace — Executa o cautare si inlocuieste rezultatele

preg_split — Desparte un sir in subsiruri

Constante predefinite modificare

PREG_PATTERN_ORDER

PREG_SET_ORDER

PREG_OFFSET_CAPTURE

PREG_SPLIT_NO_EMPTY

PREG_SPLIT_DELIM_CAPTURE

PREG_SPLIT_OFFSET_CAPTURE

Constante returnate de preg_last_error() modificare

Aceste constante sunt disponibile doar din PHP 5.2.0

PREG_NO_ERROR - Returnat in cazul în care nu au fost erori de parsare

PREG_INTERNAL_ERROR - Returnat in cazul unei erori interne PCRE

PREG_BACKTRACK_LIMIT_ERROR - Returnata in cazul depasirii pcre.backtrack_limit (numarul maxim de pasi)

PREG_RECURSION_LIMIT_ERROR - Returnata in cazul depasirii pcre.recursion_limit (cantitatea maxima de informatie pastrata pe stiva)

PREG_BAD_UTF8_ERROR - Returnat in cazul parsarii in mod UTF-8 cand intalneste o portiune de text necorespunzatoare standardului UTF-8

preg_match() modificare

int preg_match (string $pattern, string $subject [, array &$matches [, int $flags [, int $offset]]])

preg_match cauta prima aparitie a patternului in $subject.

Valoare returnata poate fi:

  • 0 - nu a fost gasita nici o potrivire
  • 1 - a fost gasita o potrivire. Odata gasita o potrivire, cautarea se opreste

Flaguri modificare

PREG_OFFSET_CAPTURE - In acest caz, in vectorul $matches este returnat primul subsir din $subject care valideaza expresia regulata.

Exemplu modificare

$subject = "Statia cu numarul 12 a fost deschisa la ora 10 si 45 de minute";
preg_match('/[0-9]+/', $subject, $matches, PREG_OFFSET_CAPTURE, 19);
print_r($matches);

preg_match_all() modificare

int preg_match_all (string $pattern, string $subject, array &$matches [, int $flags [, int $offset]])

preg_match cauta toate aparitiile patternului in $subject.

Valoare returnata poate fi:

  • 0 - nu a fost gasita nici o potrivire
  • n - au fost gasite n potriviri.

$matches modificare

  • $matches[0] - primul set de potriviri
  • $matches[0][0] - textul obtinut prin aplicarea intregului patern
  • $matches[0][1] - textul obtinut prin aplicarea primului subpatern etc
  • $matches[1] - al doilea set de potriviri

Flaguri modificare

PREG_PATTERN_ORDER

  • $matches[0] - vector cu subsirurile obtinute prin aplicarea intregului patern
  • $matches[1] - vector cu subsirurile obtinute prin aplicarea primului subpattern
  • $matches[2] - vector cu subsirurile obtinute prin aplicarea celui de-al doilea subpattern etc

PREG_SET_ORDER

  • $matches[0] - vector cu subsirurile obtinute prin prima aplicare a expresiei regulate
  • $matches[1] - vector cu subsirurile obtinute prin a doua aplicare a expresiei regulate etc.

PREG_OFFSET_CAPTURE - Are acelasi comportament cu PREG_PATTERN_ORDER dar returneaza si pozitia de start a subsirului

Exemplu modificare

$subject = "Statia cu numarul 12 a fost deschisa la ora 10 si 45 de minute";
preg_match_all('/([a-z]{4,6})|([0-9]+)/i', $subject, $matches, PREG_PATTERN_ORDER);
print_r($matches);

preg_split() modificare

array preg_split (string $pattern, string $subject [, int $limit [, int $flags]])

Returneaza un vector cu subsiruri delimitate de patternuri.

Numarul de elemente rezultate poate fi limitat la o anumita valoare. Pentru a obtine toate valorile setam limita la -1.

Flaguri modificare

PREG_SPLIT_NO_EMPTY - Returneaza doar subsirurile nevide

PREG_SPLIT_DELIM_CAPTURE - In cazul în care folosim un subpattern, stringul obtinut prin aplicarea respectivului pattern este returnat si el

PREG_SPLIT_OFFSET_CAPTURE - Este folosit pentru a returna si pozitiile fiecarui substring returnat in rezultat

Exemplu modificare

$subject = "Statia cu numarul 12 a fost deschisa la ora 10 si 45 de minute";
$matches = preg_split('/([0-9]+)/i', $subject, -1, PREG_SPLIT_OFFSET_CAPTURE);
print_r($matches);

preg_replace() modificare

mixed preg_replace ( mixed $pattern, mixed $replacement, mixed $subject [, int $limit [, int &$count]] )

Cauta si inlocuieste in $subject un set de patternuri.

Exemplu modificare

$subject = "Stația cu numărul 12 a fost deschisa la ora 10 si 45 de minute";
$matches = preg_replace('/([a-z]+) ([0-9]+)/i', "$2 $1", $subject);
print_r($matches);

Final modificare

Acest articol a fost creat avand ca scop principal familiarizarea tinerilor programatori cu folosirea PCRE. În prezent se lucrează la o nouă versiune care să cuprindă informatii ceva mai detaliate și să abordeze si subiecte complexe gen recursivitate. Orice sugestie este binevenită.

Referințe modificare