Wyrażenie regularne

Z ToProste
Skocz do: nawigacji, wyszukiwania

Wyrażenie regularne (ang. skrót regexp lub regex) jest ciągiem znaków przy pomocy którego można opisać inne ciągi znaków lub grupy ciągów wg określonych zasad.
Wyrażenie te używane są przez różnego rodzaju edytory tekstu do poszukiwania interesujących nas fragmentów tekstu, które zdefiniowane są przez wzorzec. Tekst pasujący do wzoru można zastąpić innym lub usunąć.


Historia

Wyrażenie regularne wywodzą się z teorii automatów i języka formalnego. Dziedziny te zajmują się modelami i sposobami klasyfikowania języków formalnych, które są niczym innym jak zestawem ciągów znaków.

W latach 40 XX w. Warren McCulloch i Walter Pitts opisali system nerwowy poprzez przedstawienie neuronów jako automatu. Później matematyk Stephen Kleene ujął te modele w zbiory regularne, natomiast Ken Thompson przeniósł ten zapis do edytora qed a następnie do edytora Unixowego ed i do grep'a.
Od tego czasu wyrażenia regularne są szeroko stosowane w Unixie i jego narzędziach takich jak: expr, awk, Emacs, vin, lex, Sed i PERL.
Henry Spencer napisał większość narzędzi do wprowadzenia biblioteki regex.


Wyrażenia regularne

Wyrażenie regularne w PHP

W PHP do wersji 5.2.x były używane dwa typy funkcji obsługujące wyrażenia regularne:

  • ereg* - obsługujące rozszerzone wyrażenia regularne (Extended Regular Expressions) [1]
  • preg_* - obsługujące wyrażenia regularne znane z języka PERL (zwane Basic Regular Expressions lub Perl Compatible Regular Expressions) [2]

Od wersji PHP 5.3.0 funkcje z grupy ereg uważane są za przestarzałe i nie zaleca się ich używania, skupimy się więc na funkcjach obsługujących wyrażenia regularne znane z PERL'a:


Wyrażenia regularne będziemy testować przy pomocy funkcji preg_match( wzór, badany_ciąg ), której użyjemy w poniższy sposób:

<?php 
// Jeśli ciąg znaków określony przez wyrazenie_regularne jest w badany_ciag, to wyświetli 1.
// Jeśli ciągu znaków określonych przez wyrazenie_regularne nie ma w badany_ciag, to wyświetli 0.
$wynik = preg_match( wyrazenie_regularne, badany_ciag );
echo $wynik; 
?>


Ograniczniki wyrażeń regularnych

Definicję wyrażenia regularnego przekazywanego do funkcji należy ująć w ograniczniki. Ogranicznikami może być każdy znak nie będący literą ani cyfrą.
Zwykle stosuje są ukośniki /, ale można także użyć m.in |, *, #, ! czy nawiasy ( ), [ ] oraz { }.
Ważne, aby znak użyty do zamknięcia definicji wyrażenia regularnego był taki sam jak znak otwierający.

Jeśli szukamy tekstu ala ma kota, to do funkcji przekazujemy /ala ma kota/. Gdy jako ograniczniki użyjemy znaku !, wtedy wyrażenie regularne będzie wyglądało: !ala ma kota!.

Oto przykłady kilku różnych ograniczników:

/ala ma kota/
|ala ma kota|
*ala ma kota*
#ala ma kota#
 !ala ma kota!
,ala ma kota,
[ala ma kota]
{ala ma kota}


Prosty wzorzec

Sprawdźmy czy zdanie Ola ma Asa zawiera słowo /kot/
preg_match ( '/kot/', 'Ola ma Asa' ) [5] - wynik: 0 - FAŁSZ
a teraz sprawdźmy czy znajdziemy słowo /as/
preg_match ( '/As/', 'Ola ma Asa' ) [6] - wynik: 0 - FAŁSZ
Dziwne? Otóż nie, ponieważ szukaliśmy słowa as, którego zdanie nie zawiera.
Ale słowo /As/ już znajdziemy
preg_match ( '/As/', 'Ola ma Asa' ) [7] - wynik: 1 - PRAWDA
ponieważ wzorzec w tej postaci rozróżnia wielkość liter.
A co otrzymamy dla /a/?
preg_match ( '/a/', 'Ola ma Asa' ) [8] - wynik: 1 - PRAWDA
Także jeden. Dlaczego jeden, skoro a występuje dwa razy?
A no, dla tego, że preg_match kończy działanie po znalezieniu pierwszego wystąpienia, a w tej postaci wyrażenia nie ma również znaczenia jego miejsce w przeszukiwanym tekście.


Znaki

Wyrażenia regularne mogą składać się z liter, cyfr, znaków interpunkcyjnych oraz niewidzialnych.
Litery, cyfry i wszystkie znaki niemające specjalnego znaczenia - również polskie znaki diakrytyczne, są dopasowywane w zwykły sposób.

Znaki specjalne

Wyrażenia regularne, podobnie jak ciągi znaków w PHP, pozwalają na używanie kilku znaków specjalnych, a także znaków o zadanych kodach ASCII. Ich zestawienie zawiera tabela 1. Należy zwróć uwagę, że część tych znaków pokrywa się z zestawem znaków specjalnych PHP. Może to prowadzić do powstawania nieporozumień.

Tabela 1. Znaki specjalne dozwolone w wyrażeniach regularnych
Znak specjalny HEX Opis Uwagi
\a x07 bell
\b x08 backspace dozwolony tylko wewnątrz []
\t x09 tabulacja
\n x0a line feed
\f x0c form feed
\r x0d carriage return
\e x1b escape
\cX znak sterujący Przykład: ^C (Ctrl+C) zapisujemy jako \cC
\xHH znak o zadanym kodzie szesnastkowym Przykład: \x30 (cyfra '0')
\ooo znak o zadanym kodzie ósemkowym Przykład: \101 (litera 'A')
Sprawdźmy czy to działa.
preg_match ( '/\n/', '\x0a' ) - wynik: 0 - FAŁSZ
a to
preg_match ( '/\n/', '\n' ) - wynik: 0 - FAŁSZ
Co jest? Przecież powinna być PRAWDA!
Hehe.
A teraz?
preg_match ( '/\n/', "\x0a" ) - wynik: 1 - PRAWDA
A teraz jest dobrze. ;) Gdzie jest różnica? A no, tu: '\x0a' i "\x0a".
Oba ciągi różnią się tylko tym, że pierwszy jest ujęty w apostrof, a drugi w cudzysłów.
Wyłączanie interpretacji znaków specjalnych

Zobacz też

<htmlet>zobacz-tez</htmlet>