Tartalomjegyzék
PHP Szabályos kifejezések
- Szerző: Sallai András
- Copyright © Sallai András, 2011
- Licenc: GNU Free Documentation License 1.3
- Web: https://szit.hu
Bevezetés
Reguláris kifejezések vagy Regular Expressions. Karaktersorozatokban keresek egy bizonyos mintának megfelelő karaktersorozatot. Ha megtaláltam, akkor kezdhetünk vele valamit. Törölhetjük, lecserélhetjük, vagy csak megvizsgálhatjuk egyáltalán van-e ilyen.
A PHP kétféle regex eszközt biztosít számunkra. Az egyik POSIX a másik Perl szabványon alapszik. Mi most a perl kompatibilis függvényeket nézzük meg (PCRE).
Példa sorok
Lássunk egy példát. Adott több sor. Esetünkben öt sor:
példa1
Jóska iszik a kulacsából. Iszik Jóska a kulacsából. Iszik a kulacsából Jóska. Emese iszik a kulacsából. Lajos iszik a kulacsából.
Persze lehet ez bármilyen szöveg, bármilyen karakterekkel. Lehet esetleg egy weblap forrása amelyből szeretnénk kinyeri a weboldal tartalmát a html elemek nélkül:
példa2
Lehetséges feladatok
Több feladatunk lehet. Például
- keressük meg azokat a sorokat, amelyekben szerepel az „Emese” szó.
- válogassuk ki azokat a sorokat, amelyekben szerepel a „Jóska” szó.
- olyan sorokat szeretnék, amelyben a Jóska szó a sor elején szerepel
- töröljük az összes html elemet a szövegből.
A megtalált sorokkal aztán több dolgot is tehetünk.
- vizsgálhatjuk, egyáltalán megtalálható-e (Match)
- lecseréljük másra, törölhetjük (replace)
- feldarabolhatjuk az illeszkedés mentén (split)
Alapvető szintaxis
Illeszkedés sor elején vagy végén
Elmélet
A fentiekben az egyik lehetséges feladat volt, hogy keressük meg azokat a sorokat, amelyek a „Jóska” szóval kezdődnek. Vagyis sor eleji illeszkedést kell vizsgálnunk. Ez a következő karakterrel tehetjük meg:
^
Az illeszkedés vizsgálatához készítenünk kell egy mintát, azaz egy szabályos kifejezést:
^Jóska
A szabályos kifejezés azt jelenti, amit fentebb szeretünk volna. Akkor illeszkedik, ha a sor Jóskával kezdődik.
Sor végi illeszkedés a dollár karakterrel valósítható meg:
$
Ha olyan sorokat szeretnék, amelyeknél a „Jóska” a sor végén van, akkor $ karaktert használunk a szabályos kifejezésben:
Jóska$
Ha csak olyan sorokat szeretnék, amelyben a „Jóska szó egyedül szerepel, akkor jelzem a szabályos kifejezésben, hogy illeszkedjen a sor elejére és a végére is:
^Jóska$
Egyezés keresés a gyakorlatban
Keressük azokat a sorokat, amelyek elején van Jóska:
<?php $str = <<< EOS Jóska iszik a kulacsból Iszik Jóska a kulacsból Iszik a kulacsból Jóska EOS; print preg_match("/^Jóska/", $str); ?>
Ha van ilyen sor, akkor 1-es, azaz igaz értéket kapunk. Ha nincs ilyen akkor 0-át kapunk.
A mintaillesztés esetén a minta kezdetét és végét ”/„ karakterrel jelezzük. Erre azért van szükség, mert később a minta mellett, módosítókat is fogunk használni.
Most olyan sorokat keresünk, amelyekben benne van a Jóska (bárhol):
<?php $str = <<< EOS Jóska iszik a kulacsból Iszik Jóska a kulacsból Iszik a kulacsból Jóska EOS; print preg_match("/Jóska/", $str); ?>
Most olyan sorokat keresünk, amelyekben benne van a „jóska” kisbetűvel:
<?php $str = <<< EOS Jóska iszik a kulacsból Iszik Jóska a kulacsból Iszik a kulacsból Jóska EOS; print preg_match("/jóska/", $str); ?>
Ekkor nem találunk egyezést, vagyis nullát kell kapnunk.
Most olyan sorokat keresünk, amelyekben benne van a Jóska bárhol, de az lehet kis és nagybetűs:
<?php $str = <<< EOS Jóska iszik a kulacsból Iszik Jóska a kulacsból Iszik a kulacsból Jóska EOS; print preg_match("/jóska/i", $str); ?>
Vegyük észre az beírt „i” betűt. Az „i” a case-insensitive szavakból származik, ami azt jelenti, nincs kis és nagybetűérzékenység.
<?php $str = <<< EOS Jóska iszik a kulacsból Iszik Jóska a kulacsból Iszik a kulacsból Jóska EOS; print preg_match("/jóska/", $str); ?>
Csere gyakorlat
<?php print "<!doctype html>\n<html>\n<head>\n"; print "<meta charset=\"utf-8\">\n<head>\n<body>"; $str = <<< EOS Jóska iszik a kulacsból<br> Iszik Jóska a kulacsból<br> Iszik a kulacsból Jóska<br> EOS; print preg_replace("/Jóska/", "Pista", $str); print "</body></html>"; ?>
Most beállítottam a generált html oldal karakterkódolását is, a megjelenítendő ékezetes karakterek miatt. Vegyük észre az új preg_replace() függvényt.
Most töröljük a <br> elemeket szabályos kifejezések használatával:
<?php print "<!doctype html>\n<html>\n<head>\n"; print "<meta charset=\"utf-8\">\n<head>\n<body>"; $str = <<< EOS Jóska iszik a kulacsból<br> Iszik Jóska a kulacsból<br> Iszik a kulacsból Jóska<br> EOS; print preg_replace("/<br>/", "", $str); print "</body></html>"; ?>
Darabolás gyakorlat
<?php $str = "Nagy Pista:Miskolc:Szeg utca 30.:280000"; EOS; $tomb = preg_split("/:/", $str); print "Nev: $tomb[0]<br>"; print "Telepules: $tomb[1]"; ?>
Szóközökkel elválasztott szavak:
<?php $str = "Pista Miskolc 280000"; EOS; $tomb = preg_split("/ /", $str); print "Nev: $tomb[0]<br>"; print "Telepules: $tomb[1]"; ?>
Ezt megoldhatjuk, egyszerűen egy szóköz írásával.
Előfordulhat, nemcsak szóköz, hanem bármilyen más whitespace karakterre szeretnénk illeszkedést. Ekkor használjuk az „s” helyettesítőt. Minden helyettesítő karaktert egy visszaperjel „\” vezet be:
<?php $str = "Pista Miskolc 280000"; EOS; $tomb = preg_split("/\s/", $str); print "Nev: $tomb[0]<br>"; print "Telepules: $tomb[1]"; ?>
Ekkor illeszkedni fog szóközre és tabulátorra is. Azonban még mindig csak egyetlen szóközre vagy tabulátorra illeszkedik.
Karakterek, illetve minta előfordulása
Használt szimbólumok: * + ?
Unicode karakter illeszkedése
\x{FFFF} \X \p{L}
Escape szekvenciák
\d | egy decimális szám |
\D | egy karakter, amely nem decimális szám |
\h | egy horizontális elválasztó (whitespace) karakter (PHP 5.2.4-től) |
\H | egy karaktere, amely nem horizontális elválasztó (whitespace) karakter (PHP 5.2.4-től) |
\s | egy whitespace karakter |
\S | egy karakter, amely nem elválasztó (whitespace) karakter |
\v | egy vertikális elválasztó (whitespace) karakterr (PHP 5.2.4-től) |
\V | egy karakter, amely nem vertikális elválasztó (whitespace) karakter (PHP 5.2.4-től) |
\w | egy betű vagy szám vagy aláhúzás karakter (word) |
\W | egy karakter, amely nem betű vagy szám vagy aláhúzás karakter (non-word) |
\b | Egy szóhatár (word boundary), egy hely a szó (word \w) és a nem szó (non-word) karakterek között |
\B | Nem egy szóhatár |
Karakterosztályok
Osztály | Jelentés |
---|---|
alnum | Betűk és számok |
alpha | Betűk |
ascii | A karakterkódja 0 és 127 közzé esik |
blank | szóköz vagy tabulátor |
cntrl | Kontrollkarakterek |
digit | Decimális számok (megegyezik a következővel: \d) |
graph | nyomtatható karakterek, kivéve a szóköz |
lower | kesbetűk |
nyomtatható karakterek és a szóköz | |
punct | nyomtatható karakterek a betűk és a számok kivételével |
space | white space (nem egészen egyezik meg a következővel:\s) |
upper | nagybetűk |
word | „szó” karakterek (megyegyezik a következővel: \w) |
xdigit | hexadecimális számok |
<?php $str = "abh"; if(preg_match("/[[:alpha:]]/", $str)) print "Egyezik"; else print "Nem egyezik"; ?>
Módosítók
Módosító | Állandó |
---|---|
i | PCRE_CASELESS |
m | PCRE_MULTILINE |
s | PCRE_DOTALL |
x | PCRE_EXTENDED |
U | PCRE_UNGREEDY |
X | PCRE_EXTRA |
J | PCRE_INFO_JCHANGED |
A módosítókat a minta után írjuk. Például ne legyen kis és nagybetűérzékeny:
/^valami_minta$/i
Példa a szóhatárra vágásból
Az szeretném, ha 12 karakterenként cserélje le 0 -értékre a szöveget.
<?php print "Szohatar<br>"; $str = "szerettem volna elvagni"; print preg_replace("/^(.{12,})\b/U", "0", $str); ?>
A \b a szóhatár jelöli.