Co jsou to regulární výrazy?
Regulárními výrazy se používají ke zpracovávání
textových řetězců. Vytvoříme si tzv. masku a zjišťujeme,
zda jí textový řetězec vyhovuje (např. zda se skládá
ze samých čísel…). Zda zadaný řetězec odpovídá vzoru
vyjádřeným regulárním výrazem.
http://wiki.jalakai.co.uk/include/preg.php
Použití v PHP?
Funkce preg_match() (ereg() se již dnes nepoužívá!).
Při UTF-8 kódování pak především funkce mb_ereg(),
mb_eregi() (totožné, jen mb_eregi() není citlivá na velikost
písmen. Vrací true, vyhovuje-li řetězec dané masce.
Syntaxe: mb_ereg (maska, řetězec)
Příklad:
if ( mb_ereg („den“, „Dobrý den“) )
echo „řetězec obsahuje znaky ‚den‘“;
else
echo „řetězec neobsahuje znaky ‚den‘“;
if ( preg_match („/den/“, „Dobry den“) )
if ( preg_match („/den/i“, „Dobry den“) )
// nebude citlivá na velikost písmen
Je v řetězci obsažen podřetězec?
Maska skládající se z pouhých znaků hledá výskyt tohoto
podřetězce v daném řetězci
program
dobrý den
programování
maska:
řetězec:
den
dobrý den
maska:
řetězec:
PŘÍKLAD: Je v řetězci obsažen podřetězec?
denně se potkáváme
škola
Tečka jako libovolný znak
Tečka zastupuje jakýkoliv jeden znak
gr.m
program
maska:
řetězec:
bagr může závodit
grimasa
agronom
je.en
jeden, dva, tři
maska:
řetězec:
Kdo je ten muž?
pr....m
složitý program
maska:
řetězec:
prodám počítač
PŘÍKLAD: Tečka jako libovolný znak
Jen vybrané znaky
Výběr z několika konkrétních znaků za pomoci hranatých
závorek []
dobr[ýé]
dobrý den
maska:
řetězec:
dobrou noc
dobré jídlo
á.[123]
Kobra 11
maska:
řetězec:
PŘÍKLAD: Jen vybrané znaky
Olomoucká 39
kódovaná 16-ti bity
Příklad:
Napište regulární výraz, který potvrdí, že se v řetězci
nachází alespoň jedna samohláska „a“, „e“, „i“, „o“, „u“, „y“.
Například:
strč prst skrz krk
ahoj světe
[aeiouy]
Řešení:
Jen vybrané znaky - rozsah
Často nemusíme do hranatých závorek vypisovat všechny
znaky, které potřebujeme ošetřit, ale použít rozsah
Například:
[0-9] místo [0123456789]
[a-z] místo [abcdefghijklmnopqrstuvwxyz]
[A-Z] místo [ABCDEFGHIJKLMNOPQRSTUVWXYZ]
Lze kombinovat:
[0-9a-dA-D] místo [0123456789abcdABCD]
Příklad:
Napište regulární výraz, který vyhodnotí, zda se v řetězci
nachází časový údaj ve tvaru HH:MM.
Například: 16:15
08:59
00:01
[0-2][0-9]:[0-5][0-9]
Řešení:
Negace
Chceme-li vybrat znaky, které naopak nechceme, můžeme
použít negaci. Značí se stříškou ^ a píše se hned
za otevírací hranatou závorku, např. [^abc]
[^A-Z]
a
maska:
řetězec:
AbC
ABC
PŘÍKLAD: Negace
[^1][^ ][0-3]
123
maska:
řetězec:
953
9 3
-123
Jak zapsat speciální znaky jako je např. tečka?
Pokud mají znaky speciální význam a my jej chceme
pro daný případ potlačit, připíšeme před ně zpětné
lomítko \
Atd\.
jablko, hruška atd.
maska:
řetězec:
jablko, hruška atd atd
Příklad č. 1:
Napište regulární výraz, který vyhodnotí, zda řetězec
obsahuje tři tečky.
Například:
leden, únor, březen…
\.\.\.
Řešení:
Příklad č. 2:
Napište regulární výraz, který vyhodnotí, zda se v řetězci
nachází číslice v hranatých závorkách
Například:
[5]
\[[0-9]\]
Řešení:
Co když napíšeme do hranatých závorek
metaznaky plnící speciální funkci?
Pokud je ve výčtu (v hranatých závorkách) uvedena tečka,
je brána jako normální znak . a se zpětným lomítkem se
nepíše.
Pokud je ve výčtu uvedena stříška ^ na jiné pozici
než ihned za otevírací hranatou závorkou [, je rovněž
brána jako normální znak.
[.#^][a-z]
^x
maska:
řetězec:
z-(x.y)
Počátek a konec
Pokud chceme ověřovat znaky na začátku řetězce,
použijeme na počátku stříšku ^. Pro určení konce řetězce
zase na konci dolar $.
^den$
den
maska:
řetězec:
dobrý den
PŘÍKLAD: Počátek a konec
[0-9]$
náměstí Svobody
maska:
řetězec:
náměstí Svobody 18
agent 007
1
Opakování výrazu pomocí hvězdičky I.
Pomocí kvantifikátoru * bude regulární výraz opakován
kolikrát to jen bude možné (0x až n-krát)
[0-9]*
646541216546541231123
maska:
řetězec:
9. třída
dobrý den
PŘÍKLAD 1: Opakování výrazu pomocí * I.
Napište regulární výraz, který potvrdí, že se v řetězci
nacházejí samotná čísla (nebo je prázdný)
^[0-9]*$
Řešení:
PŘÍKLAD 2: Opakování výrazu pomocí * I.
^[0-9][^0-9]*$
1 slon
maska:
řetězec:
10 slonů
1 slon a 1 zebra
1
Opakování výrazu pomocí hvězdičky II.
Zápis .* znamená libovolný řetězec znaků
^[0-9].*[0-9]$
0 jedna 2
maska:
řetězec:
0 jedna dvě
01
0
PŘÍKLAD 1: Opakování výrazu pomocí * II.
Napište regulární výraz, který potvrdí, že se v řetězci
nachází věta – začíná velkým písmenem nebo číslem
a končí tečkou. (Pomiňte, že vět v řetězci může být víc
za sebou.)
Například:
Ahoj světe.
^[A-Z0-9].*\.$
Řešení:
Opakování pomocí plus
Pomocí kvantifikátoru + bude regulární výraz opakován
minimálně jedenkrát (1x až n-krát)
[0-9]+
Kill Bill
maska:
řetězec:
Kill Bill 2
PŘÍKLAD: Opakování pomocí plus
Napište regulární výraz, který ověří, že se zadaná
přezdívka skládá jen z malých písmen bez diakritiky, která
mohou být rozdělena podtržítkem _. Délka přezdívky je
minimálně 2 znaky a podtržítko nemůže být na první pozici.
Například:
jirka _jirka
jirka_novak Jirka_Novak
^[a-z][a-z_]+$
Řešení:
Opakování pomocí otazníku
Pomocí kvantifikátoru ? bude regulární výraz opakován
maximálně jednou (0x nebo 1x)
^škola?$
škola
maska:
řetězec:
škol
střední škola
PŘÍKLAD: Opakování pomocí otazníku
pr?.*gram
programátor
maska:
řetězec:
pentagram
pět gramů
Určený počet opakování I.
Chceme-li vymezit přesný počet opakování, použijeme
zápis {x}
^x{2}$maska:
řetězec:
xx
xxx
x
xxxx
Určený počet opakování II.
Chceme-li vymezit rozsah, kolikrát se může výraz
maximálně opakovat, použijeme složené závorky {x,y}
^x{2,3}$maska:
řetězec:
xx
xxx
x
xxxx
Určený počet opakování III.
Chceme-li vymezit rozsah způsobem „minimálně x-krát“,
použijeme zápis {x,}
^x{2,}$maska:
řetězec:
xx
xxx
x
xxxx
PŘÍKLAD 1: Určený počet opakování
mate{0,3}matika
matematika
maska:
řetězec:
automat a automatika
mate mě matematika
PŘÍKLAD 2: Určený počet opakování
Napište regulární výraz, který ověří, že zadaný řetězec má
minimálně 4 znaky.
^.{4,}$
Řešení:
Jedno, nebo druhé
Použitím svislé čáry |, která má význam logického OR,
bude platit jen určitá hodnota z daného výčtu.
^a|b|c$maska:
řetězec:
b
c
a
d
Seskupování pomocí kulatých závorek
Kulaté závorky () používáme k vytvoření podvýrazu.
Dojde k seskupení jednotlivých částí řetězce
a doplněné kvantifikátory * + ? se pak budou vztahovat
na celý podvýraz.
(kočka|pes)+maska:
řetězec:
Na dvorku si hraje pes.
Na dvorku si hrají kočky a psi.
Na dvorku si hraje kočka.
Na dvorku si nikdo nehraje.
PŘÍKLAD: Seskupování pomocí kulatých…
^([0-9]{1,2},)+$
Řešení:
Napište regulární výraz, který ověří, že jsou v řetězci pouze
čísla v rozsahu 0 – 99 a za každým číslem se nachází
čárka.
Například:
1,8,
11,1,22,2,
Začátek a konec slova
Zda stojí slovo samostatně můžeme ověřit pomocí
metaznaků [[:<:]] a [[:>:]], které označují začátek a
konec slova. Samozřejmě je možné použít každý z nich
nezávisle.
[[:<:]]svět[[:>:]]maska:
řetězec:
ahoj světe
Takový je svět.
svět kolem nás
Třídy znaků I.
Třídy jsou skupiny znaků, které pro snadnější práci
s regulárními výrazy přednastavili sami autoři jazyka PHP.
Syntaxe:
[[:název třídy:]]
Jednotlivé třídy:
alnum písmena anglické abecedy a desítkové
číslice
alpha písmena anglické abecedy
Třídy znaků II.
lower malá písmena anglické abecedy
upper velká písmena anglické abecedy
digit čísla (desítková soustava)
xdigit čísla (šestnáctková soustava)
punct interpunkční znaménka a další znaky
(závorky, zavináče atd.)
blank mezera a tabulátor
space prázdné znaky (mezera, tabulátor, nová řádka,
nová stránka atd.)
Třídy znaků III.
cntrl řídící znaky (\n, \t atd.)
print tisknutelné znaky
graph tisknutelné znaky bez mezer
Regulární výraz pomocí tříd, který ověří, že řetězec je číslo
desítkové soustavy.
Ukázkový příklad na třídu znaků
^[[:digit:]]+$
PŘÍKLAD: Třídy znaků
^[a-zA-Z0-9.]+@[[:alnum:]]+\.[[:alnum:]]{2,4}$
Řešení:
Napište základní regulární výraz, který zkontroluje platnost
e-mailové adresy
OBECNÝ PŘÍKLAD Č. 1:
^[0-9]{3}[a-z0-9]+$
Řešení:
Napište regulární výraz, který ověří, že uživatelem zadané
znaky splňují tyto nároky na heslo:
• pouze číslice a malá písmena
• minimální délka 4 znaky
• první 3 znaky musejí být číslice
OBECNÝ PŘÍKLAD Č. 2:
^[1-9]{1}[0-9]*$
Řešení:
Napište regulární výraz, který ověří, že uživatel zadal číslo
(i z více číslic) a pokud ano, tak že nezačíná nulou nebo
nulami.
Například:
42
042
OBECNÝ PŘÍKLAD Č. 3:
^[^ ]*$
Řešení:
Napište regulární výraz, který potvrdí, že se v řetězci
nenachází žádná mezera.
3. parametr u funkcí mb_ereg() a mb_eregi()
Třetím, nepovinným parametrem těchto funkcí je pole
shod. Do něj se uloží ty části řetězce, které vyhovují
danému podvýrazu regulárnímu výrazu (podvýraz je
v kulatých závorkách). V indexu [0] pole se uloží ta část
řetězce, která vyhovuje celému regulárnímu výrazu.
Například:
if (mb_ereg("(ahoj) světe (veliký)","ahoj světe veliký",$pole))
print_r($pole);
// vypíše: Array ([0]=>ahoj světe veliký [1]=>ahoj [2]=>veliký)
?>
PŘÍKLAD: Třetí parametr u funkcí…
Doplňte regulární výraz, díky kterému bude možné vypsat
první číslo (i z více číslic), které se v řetězci objeví.
if ( mb_ereg („............","James Bond, agent 007.",$pole) )
echo $pole[1];
?>
V tomto případě bude vypsáno: 007
^[^0-9]*([0-9]*).*$
Řešení:
mb_ereg_replace() a mb_eregi_replace() I.
Tyto funkce se opět liší jen citlivostí na velikost písmen.
Mají tuto syntaxi:
mb_ereg_replace(regulární výraz, náhrada, pův.řetězec)
Příklad:
$a = mb_ereg_replace ("(ahoj) světe", "nazdar", "ahoj světe");
echo $a;
// vypíše: nazdar
?>
Ve druhém parametru určujícím nahrazovaný řetězec lze
použít metaznak \\číslice určující podvýraz regulárního
výrazu.
mb_ereg_replace() a mb_eregi_replace() II.
Například:
$a = mb_ereg_replace ("(ahoj) (světe) (veliký)", "\\3 \\2 \\1",
"ahoj světe veliký");
echo $a;
// vypíše: veliký světe ahoj
?>
PŘÍKLAD: Funkce ereg_replace() a …
Pomocí funkce mb_eregi_replace nahraďte v textu
[B] a [/B] za HTML tagy a . Například:
„následující bude tučně: [B]výraznější text[/B]“
změnit na
„následující bude tučně: výraznější text“
Řešení:
$text = "následující bude tučně: [B]výraznější text[/B]";
echo mb_ereg_replace ("\[B\](.*)\[/B\]*", "\\1", $text);
?>
pokračování…
Hladovost
… daný příklad sice bude u naší testovací věty fungovat,
nicméně stačilo by do řetězce doplnit další prvky
pro zvýraznění textu a výraz nesplní, co očekáváme:
následující bude tučně: [B]výraznější text[/B] a další [B]tučný[/B]
Při použití stejného regulárního výrazu výsledkem bude:
následující bude tučně: výraznější text[/B] a další [B]tučný
Důvod je prostý – regulární výraz se snaží obsáhnout
co nejvíce znaků z řetězce a za koncové [/B] tak vezme až
následující bude tučně: [B]výraznější text[/B] a další [B]tučný[/B]
Tuto skutečnost je třeba mít při sestavování výrazů na paměti.
Funkce split() a spliti()
Tyto funkce umějí rozdělit řetězec na několik částí a ty pak
uložit do jednotlivých prvků pole. Mají tuto syntaxi:
split (regulární výraz, řetězec, [limit])
Řetězec je rozložen podle regulárního výrazu
(na maximální počet částí, které udává limit)
Například (rozdělení řetězce po slovech a uložení do pole):
$pole = split ("[[:blank:]]+", „ahoj světe veliký");
print_r ($pole);
// vypíše: Array ( [0] => ahoj [1] => světe [2] => veliký )
?>