PHP - Regularni izrazi (Regular Expressions)


Šta je regularno izražavanje?

Regularni izrazi, poznatiji kao "regex" ili "RegExp", posebno su oblikovani tekstualni stringovi koji se koriste za pronalaženje obrazaca u tekstu. Regularni izrazi jedan su od najsnažnijih alata koji su danas dostupni za efikasnu obradu teksta i manipulacije. Na primjer, može se koristiti za provjeru da li je format podataka, tj. ime, adresa e-pošte, telefonski broj itd. koji je korisnik unio, tačan ili nije, pronalazak ili zamjena odgovarajućeg niza unutar tekstualnog sadržaja itd.

PHP (verzija 5.3 i novija) podržava regularne izraze u Perl stilu putem svoje preg_ family funkcije. Zašto regularni izrazi u Perl stilu? Budući da je Perl (praktično izdvajanje i jezik izvještaja) bio prvi uobičajeni programski jezik koji je pružao integrisanu podršku za regularne izraze i poznat je po snažnoj podršci regularnim izrazima i izvanrednim mogućnostima obrade i manipulacije tekstom. Počnimo sa kratkim pregledom najčešće korištenih PHP-ovih ugrađenih funkcija za podudaranje uzoraka prije nego što uđemo duboko u svijet regularnih izraza.

Funkcija Šta radi
preg_match() Izvrši podudaranje regularnog izraza.
preg_match_all() Izvrši globalno podudaranje regularnih izraza.
preg_replace() Izvrši pretraživanje i zamjenu regularnih izraza.
preg_grep() Vraća elemente ulaznog niza koji se podudaraju s uzorkom.
preg_split() Dijeli string u podnizove pomoću regularnog izraza.
preg_quote() Citiraj znakove regularnog izraza pronađene unutar stringa.


Sintaksa regularnog izraza

Sintaksa regularnog izraza uključuje upotrebu posebnih znakova (ne brkajte sa HTML specijalnim znakovima). Znakovi kojima se u regularnom izrazu daje posebno značenje su: . *? + [] () {} ^ $ | \. Moraćete iskrivite ove znakove kad god ih želite doslovno koristiti. Na primjer, ako želite podudarati s ".", morali biste napisati \. . Svi ostali znakovi automatski poprimaju svoja doslovna značenja. Sljedeći dijelovi opisuju različite opcije dostupne za formulisanje obrazaca:



Klase karaktera

Uglaste zagrade koje okružuju uzorak znakova nazivaju se klasa znakova, npr. [abc]. Klasa znakova uvijek se podudara s jednim znakom s popisa navedenih znakova, što znači da se izraz [abc] podudara samo sa znakom a, b ili c. Takođe se mogu definisati negativne klase znakova koje se podudaraju s bilo kojim znakom, osim onim koji se nalaze u zagradama. Negirana klasa znakova definiše se stavljanjem znaka (^) odmah nakon uglaste zagrade, poput ove [^abc]. Takođe možete definisati raspon znakova pomoću crtice (-) unutar klase znakova, poput [0-9]. Pogledajmo nekoliko primjera klasa karaktera:

RegExp Šta radi
[abc] Odgovara bilo kojim od znakova a, b ili c.
[^abc] Odgovara bilo kojim drugim znakom osim a, b ili c.
[a-z] Odgovara bilo kojim znakom od malog a do malog z.
[A-Z] Odgovara bilo kojem znaku od velikog slova A do velikog slova Z.
[a-Z] Odgovara bilo kojem znaku od malog slova a do velikog slova Z.
[0-9] Odgovara jednoj cifri između 0 i 9.
[a-z0-9] Odgovara jedan znak između a i z ili između 0 i 9.

Sljedeći primjer će vam pokazati kako pronaći postoji li obrazac u nizu koristeći regularni izraz i PHP funkciju preg_match():

<?php
$pattern = "/ca[kf]e/";
$text = "Jeo je kolač u kafiću.";
if(preg_match($pattern, $text)){
    echo "Pronađeno podudaranje!";
} else{
    echo "Nije pronađeno podudaranje.";
}
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Podudaranje obrazac sa nizom pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/ca[kf]e/";
$text = "Jeo je kolač u kafiću.";
if(preg_match($pattern, $text)){
    echo "Pronađeno podudaranje!";
} else{
    echo "Nije pronađeno podudaranje.";
}
?>

</body>
</html>

Slično tome, možete koristiti funkciju preg_match_all() da biste pronašli sva podudaranja unutar niza:

<?php
$pattern = "/ca[kf]e/";
$text = "Jeo je kolač u kafiću.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađeno podudaranje.";
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Pronađi sve pojave uzorka u nizu koristeći RegEx u PHP-u</title>
</head>
<body>

<?php
$pattern = "/ca[kf]e/";
$text = "Jeo je kolač u kafiću.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađeno podudaranje.";
?>

</body>
</html>


Unaprijed definisane klase znakova

Neke klase znakova poput znakova, slova i bijelih prostora koriste se tako često da za njih postoje nazivi prečica. Sljedeća tabela navodi one predefinisane klase znakova:

Prečica Šta radi
. Podudara se sa bilo kojem pojedinačnom znaku, osim novog reda \n.
\d Podudara se sa bilo kojim znakom. Isto kao [0-9]
\D Podudara se sa bilo kojim ne-cifrenim znakom. Isto kao [^0-9]
\s Podudara se sa bilo kojim razmakom (znak razmaka, kartice, novog reda ili znaka za vraćanje karaktera). Isto kao [\t\n\r]
\S Podudara se sa bilo kojim znakom koji nije razmak. Isto kao [^ \t\n\r]
\w Podudara se sa bilo kojim znakom riječi (definiše se kao a do z, A do Z, 0 do 9 i donja crta). Isto kao [a-zA-Z_0-9]
\W Podudara se sa bilo kojim znakom koji nije riječ. Isto kao [^a-zA-Z_0-9]

Sljedeći primjer će vam pokazati kako pronaći i zamijeniti razmak crticom u nizu pomoću regularnog izraza i PHP funkcije preg_replace():

<?php
$pattern = "/\s/";
$replacement = "-";
$text = "Zemlja se vrti oko\nthe\tSun";
// Zamijenite razmake, nove redove i kartice
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
// Zamijenite samo razmake
echo str_replace(" ", "-", $text);
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Pronalaženje i zamjena znakova u stringu pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/\s/";
$replacement = "-";
$text = "Zemlja se vrti oko\nthe\tSun";
// Zamijenite razmake, nove redove i kartice
echo preg_replace($pattern, $replacement, $text);
echo "<br>";
// Zamijenite samo razmake
echo str_replace(" ", "-", $text);
?>

</body>
</html>


Kvantifikatori ponavljanja

U prethodnom smo dijelu naučili kako upariti jedan karakter na razne načine. Ali što ako želite podudaranje s više od jednog karaktera? Na primjer, recimo da želite otkriti riječi koje sadrže jedan ili više primjera slova p ili riječi koje sadrže najmanje dva p i tako dalje. Tu u obzir dolaze kvantifikatori. Kvantifikatorima možete odrediti koliko puta se znak u regularnom izrazu treba podudarati. Sljedeća tabela navodi različite načine za kvantifikovanje određenog uzorka:

RegExp Šta radi
p+ Podudara se sa jednom ili više pojava slova p.
p* Podudara se sa nula ili više pojava slova p.
p? Podudara se sa nula ili jednom pojavom slova p.
p{2} Podudara se tačno sa dva pojavljivanja slova p.
p{2,3} Podudara se s najmanje dva pojavljivanja slova p, ali ne više od tri pojavljivanja slova p.
p{2,} Podudara se s dva ili više pojavljivanja slova p.
p{,3} Podudara se sa najviše tri pojavljivanja slova p.

Regularni izraz u sljedećem primjeru razdvaja string na zarez, niz zareza, razmak ili kombinaciju istih, koristeći PHP funkciju preg_split():

<?php
$pattern = "/[\s,]+/";
$text = "Moje omiljene boje su crvena, zelena i plava";
$parts = preg_split($pattern, $text);
 
// Pregledajte niz dijelova i prikažite podnizove
foreach($parts as $part){
    echo $part . "<br>";
}
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Podijelite string pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/[\s,]+/";
$text = "Moje omiljene boje su crvena, zelena i plava";
$parts = preg_split($pattern, $text);
 
// Pregledajte niz dijelova i prikažite podnizove
foreach($parts as $part){
    echo $part . "<br>";
}
?>

</body>
</html>


Položaj sidra (Position Anchors)

Postoje određene situacije u kojima želite podudaranje na početku ili na kraju reda, riječi ili stringa. Da biste to učinili, možete koristiti sidra. Dva uobičajena sidra su kareta (^) koja predstavlja početak stringa i znak dolara ($) koji predstavljaju kraj stringa.

RegExp Šta radi
^p Podudara se sa slovom p na početku reda.
p$ Podudara se sa slovom p na kraju retka.

Regularni izraz u sljedećem primjeru prikazaće samo ona imena iz niza imena koja počinju slovom "M" koristeći PHP funkciju preg_grep():

<?php
$pattern = "/^M/";
$names = array("Marko Marković", "Miloš Mihaljica", "Musa Musić");
$matches = preg_grep($pattern, $names);
 
// Pregledajte niz podudaranja i prikažite odgovarajuća imena
foreach($matches as $match){
    echo $match . "<br>";
}
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Podudaranje stringa počevši sa određenim znakovima pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/^M/";
$names = array("Marko Marković", "Miloš Mihaljica", "Musa Musić");
$matches = preg_grep($pattern, $names);
 
// Pregledajte niz podudaranja i prikažite odgovarajuća imena
foreach($matches as $match){
    echo $match . "<br>";
}
?>

</body>
</html>


Modifikatori uzorka

Modifikator uzorka vam omogućava da kontrolišete način na koji se rukuje podudaranjem uzorka. Modifikatori uzorka postavljaju se neposredno nakon regularnog izraza, na primjer, ako želite tražiti uzorak na način koji ne razlikuje velika i mala slova, možete koristiti modifikator i, poput ovog: /pattern/i. Sljedeća tabela navodi neke od najčešće korištenih modifikatora uzoraka.

Modifikator Šta radi
i Čini da se podudaranje ne razlikuje od malih i velikih slova.
m Mijenja ponašanje ^ i $ kako bi se podudarali s granicom nove linije (tj. početkom ili krajem svake linije unutar stringa s više linija), umjesto granice stringa.
g Izvršava globalno podudaranje, tj. pronalazi sve pojave.
o Procjenjuje izraz samo jednom.
s Mijenja ponašanje . (tačka) kako bi se podudarali sa svim znakovima, uključujući nove redove.
x Omogućava vam korištenje razmaka i komentara u regularnom izrazu radi jasnosti.

Sljedeći primjer će vam pokazati kako izvršiti globalno pretraživanje bez velikih i malih slova pomoću i modifikatora i PHP funkcije preg_match_all().

<?php
$pattern = "/boja/i";
$text = "Crvena boja je vidljivija od plave na dnevnom svjetlu.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađenih podudaranja.";
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Podudaranje obrazca na način koji ne razlikuje velika i mala slova pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/boja/i";
$text = "Crvena boja je vidljivija od plave na dnevnom svjetlu.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađenih podudaranja.";
?>

</body>
</html>

Slično tome, sljedeći primjer pokazuje kako se podudara na početku svakog reda u višerednom nizu pomoću modifikatora ^ i m s funkcijom preg_match_all().

<?php
$pattern = "/^boja/im";
$text = "Crvena boja je vidljivija od \nboja plave na dnevnom svjetlu.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađenih podudaranja.";
?>
Pogledajmo kako koristiti primjer u praksi:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Podudaranje obrazca na način koji ne razlikuje velika i mala slova pomoću RegEx-a u PHP-u</title>
</head>
<body>

<?php
$pattern = "/^boja/im";
$text = "Crvena boja je vidljivija od \nboja plave na dnevnom svjetlu.";
$matches = preg_match_all($pattern, $text, $array);
echo $matches . " pronađenih podudaranja.";
?>

</body>
</html>


Granice riječi

Znak s granicom riječi (\b) pomaže vam u pretraživanju riječi koje počinju i/ili završavaju uzorkom. Na primjer, regexp /\bauto/ podudara se s riječima koje počinju s uzorkom automobila i podudarao bi se s: autobus, automat ili autoritet, ali se ne bi podudarao s riječi kamion. Slično tome, regexp /auto\b/ podudara se s riječima koje se završavaju s uzorkom auto i odgovarala bi riječi superauto, ali se ne bi podudarao s riječi kolicima. Isto tako, /\bauto\b/ podudara se s riječima koje počinju i završavaju s uzorkom auto i odgovarao bi samo riječi auto. Sljedeći primjer će naglasiti riječi koje počinju s auto podebljano:

<?php
$pattern = '/\bauto\w*/';
$replacement = '<b>$0</b>';
$text = 'Riječi koje počinju s auto: automobil, autobus, automat. Riječ koja se završavaju s auto: superauto.';
echo preg_replace($pattern, $replacement, $text);
?>

Nadamo se da ste razumjeli osnove regularnog izražavanja. Da biste naučili kako provjeriti valjanost podataka obrazaca pomoću regularnog izraza, pogledajte lekciju za provjeru valjanosti obrazaca PHP.