Co to są wyrażenia regularne i do czego służą?

Z PHPEdia.pl
Skocz do: nawigacji, wyszukiwania

Wyrażenia regularne (ang. regular expressions, w skrżcie: regex bądź regexp) to wzorce opisujące łańcuchy znaków. Za ich pomocą możemy wyszukiwać określone wzorcem ciągi tekstow bądź zastąpować fragmenty ciągów wg określonego wzorca.

PHP Udostępnia nam funkcje do obsługi dwżch standardów wyrażeś regularnych:

  • o rozszerzonej składni POSIX
  • zgodne z Perlem (PCRE)

przykłady

Wyrażenia POSIX

Najbardziej podstawową funckją jest ereg, którą można wykorzystać do sprawdzenia czy określony tekst speśnia warunek określony w wyrażeniu regularnym, np.

<?php
$test = 'PEPE próbuje coś napisać';
 
if (ereg('PEPE', $test)) {
 echo '$test zawiera łańcuch "PEPE".';
} else {
 echo '$test nie zawiera łańcucha "PEPE".';
}
?>

Należy jednak pamiętać ze funkcja ereg zwraca uwagę na wielkość liter, nie ma się czym przejmować ponieważ istnieje funkcja eregi która działał prawie tak samo jak ereg jedyną różnicć jest to że funkcja eregi nie zwraca uwagi na wielkość liter. np.

<?php
$test = 'PePe próbuje coś napisać';
 
if (eregi('PEPE', $test)) {
 echo '$test zawiera łańcuch "PEPE".';
} else {
 echo '$test nie zawiera łańcucha "PEPE".';
}
?>

W wyrażeniach regularnych można używać specjalnych kodów:

znak ^ (daszek) - służy do oznaczania początku łańcucha
znak $ (dolar) - służy do oznaczenia końca łańcucha
znak ? (pytajnik) - oznacza że "poprzedni znak jest opcjonalny"
znak + (plus) - oznacza że "jeden lub więcej poprzedzających znaków jest opcjonalnych"
znak * (gwiazdka) - oznacza że "zero lub więcej poprzedzających znaków jest opcjonalnych"

W tym momencie nasuwa się pytanie co zrobić gdy chcemy w łańcuchu znaków odnaleźć znaki które mają specjalne znaczenie np. $,^ ? Wtedy wystarczy poprzedzić te znaki znakiem ucieczki (lewym ukośnikiem).


Formatowanie tekstu za pomocą wyrażeń regularnych.

Funkcja ereg_replace działał podobnie jak funkcja ereg, jednak funkcja ereg_replace pobiera jeszcze trzeci parametr. Funkcja ereg_replace wygląda następująco:

$text = ereg_replace(wyrażenie_regularne, zastąpić_tekstem, stary_tekst);

Już pewnie każdy domyślił się, że istnieje również funkcja eregi_replace i różni się od funkcji ereg_replace tylko tym, że nie zwraca uwagi na wielkość liter.

W ten sposób przechodzimy do prostego lecz przydatnego formatowania tekstu.

Pogrubienie tekstu:

$text = eregi_replace('\\[b]', '<strong>', $text);
$text = eregi_replace('\\[/b]', '</strong>', $text);

Kwadratowy nawias ([) w wyrażeniach regularnych oznacza początek zestawu dopasowanych znaków, dlatego wstawiamy przed nim znak ucieczki (lewy ukośnik) aby zneutralizować jego specjalne znaczenie. Należy również pamiętać ze w łańcuchach PHP lewe ukośniki (\) mają również specjalne znaczenie, dlatego musimy wstawią kolejny lewy ukośnik. część osób pewnie zastanawia się dlaczego zamykający nawias kwadratowy nie jest poprzedzony znakami ucieczki (lewymi ukośnikami), odpowiedź jest prosta, jeżeli otwierający nawias kwadratowy zostanie pozbawiony specjalnego znaczenia to zamykający nawias kwadratowy automatycznie je traci, wiąc nie musimy przed nim stosować lewych ukośników, ale gdy je tam zastosujemy nic się nie stanie.

Skorzystaliśmy z funkcji eregi_replace z tego powodu aby można było stosować znaczniki [b], [/b] jak i [B], [/B].

Kursywa:

$text = eregi_replace('\\[i]', '<em>', $text);
$text = eregi_replace('\\[/i]', '</em>', $text);

Jak widać kursywę robimy analogicznie do efektu pogrubienia, w powyższych przykładach zostały zastosowane znaczniki (pogrubienie) i (emfaza) ponieważ takie są najnowsze standardy HTML'a.

Formatowanie akapitów:

W tym przypadku moglibyśmy postąpić analogicznie do powyższych przykładów, lecz istnieje prostsze rozwiązanie.

$text = ereg_replace("\r", '', $text);
$text = ereg_replace("\n\n", '</p><p>', $text);
$text = ereg_replace("\n", '<br />', $text);

Wyrażenia PCRE

PCRE - Perl-Compatible Regular Expressions - wyrażenia regularne zgodne z tymi z Perla.

<?php
 
/*
 * przykład 1:
 * zamieniamy cudzysłowy na kursywć w HTML
 */
 
$sStr = 'Wśród nich znakomicie przyjęty "Banquet" i obecny singel "Helicopter".';
$sPattern = '/"(.*?)"/';
$sReplacement = '<i>\1</i>';
 
echo preg_replace($sPattern, $sReplacement, $sStr);
 
//wyświetli:
//Wśród nich znakomicie przyjęty <i>Banquet</i> i obecny singel <i>Helicopter</i>.
 
 
/*
 * przykład 2:
 * prosta walidacja adresu email
 */
 
$sPattern = '/[a-z0-9_.]+@[a-z0-9.-]+\.[a-z0-9]{2,}/i';
$aStrings = array('szefu_23@example.com',
                  'szefu_23@example.pl',
                  'sZEFu_23@example.com',
                  'szefu_23 @ example.pl',
                  'szefu_23@example.c',
                  'szefu_23@example'
                 );
 
foreach($aStrings as $sStr)
{
    if(preg_match($sPattern, $sStr))
    {
        echo "tak ";
    }
    else
    {
        echo "nie ";
    }
 
}
 
//wyświetli:
//tak tak tak nie nie nie
 
?>

Klasy znaków

Stosowane w wyrażeniach regularnych POSIX

  • [[:alnum:]] - Znaki alfanumeryczne
  • [[:alpha:]] - Znaki alfabetu
  • [[:lower:]] - małe litery
  • [[:upper:]] - Wielkie litery
  • [[:digit:]] - Liczby dziesiętne
  • [[:xdigit:]] - Liczby szesnastkowe
  • [[:punct:]] - Znaki przestankowe
  • [[:blank:]] - Tabulatory i spacje
  • [[:space:]] - Pusta przestrześ
  • [[:cntrl:]] - Znaki kontrolne
  • [[:print:]] - Wszystkie możliwe do wyświetlenia znaki
  • [[:graph:]] - Wszystkie mozliwe do wyświetlenia znaki poza spacjami
  • \ - znak ucieczki
  • ^ - dopasowanie na początku ciągu
  • $ - dopasowanie na koścu ciągu
  • . - dopasowanie do każdego znaku oprócz nowego wiersza
  • | - start alternatywnych rozgaśćzieś (jak OR)
  • ( - początek ciagu
  • ) - koniec ciągu
  • * - powtżrzenie zero lub wiecej razy
  • + - powtżrzenie jeden lub więcej razy
  • { - początek minimalnego/maksymalnego kwantyfikatora
  • } - koniec minimalnego/maksymalnego kwantyfikatora

Powtarzalność

Jeżeli zachodzi potrzeba określenia kilkukrotnego występowania jakiegoś ciągu lub klasy znaków, można zastosować dwa znaki specjalne w wyrażeniach regularnych:

  • Symbol *, który oznacza że symbol może powtórzyć się zero lub więcej razy
  • Symbol +, który oznacza jeden lub więcej razy

Na przykład:

[[:alnum:]]+

oznacza "co najmniej jeden znak alfanumeryczny"

Podwyrażenia

Czasami konieczne jest rozdzielenie jednego wyrażenia na podwyrażenia. Na przykład "co najmniej jeden z tych ciągów, a nastepnie dokładnie tego".

(bardzo)*dużo

pasuje do "dużo","bardzo dużo","bardzo bardzo dużo" ...

Podwyrażenia policzalne

Możliwe jest określenie liczby powtórzeń danego ciągu przez zastosowanie nawiasów klamrowych. Na przykład:

(bardzo){1,3}

pasuje do "bardzo","bardzo bardzo" i "bardzo bardzo bardzo", ale już nie do "bardzo bardzo bardzo bardzo"

Linki zewnętrzne