Wyrażenia regularne PHP – preg_replace
- Mateusz Żeromski | 2008-05-14 | Php
Dla wielu początkujących i czasem dla średnio-zaawansowanych programistów wielką tajemnicą jest umiejętność posługiwania się wyrażeniami regularnymi. Problem zazwyczaj polega na tym, że ten sam efekt można uzyskać zastępując wyrażenia regularne kombinacjami explode, str_replace, substr itp. Lecz jest to więcej pracy i taki kod nie wygląda za dobrze.
Wyrażenia regularne – co to jest?
Najprościej można by określić ten temat jako nakładanie wzorców na istniejący string.
Nauczenie się obsługi funkcji wyrażeń regularnych tj.
- preg_grep
- preg_last_error
- preg_match_all
- preg_match
- preg_quote
- preg_replace_callback
- preg_replace
- preg_split
jest banalne – trzeba tylko 2 do 3 godzin nauki i już do końca życia nie zapomnimy tego :)
Podstawy
Jak napisałem wcześniej wyrażenia regularne są „wzorcem” jakiegoś danego stringa, podstawową funkcją z tego działu jest „preg_replace”, przyjmuje ona standardowo trzy parametry:
- wzorzec
- informację jaką daną wyciągnąć
- string
Oczywiście największy problem jest z pierwszą i drugą wartością. W przykładzie prezentuję skrypcik który wykorzystuje kilka możliwości wyrażeń regularnych – myślę, że po ich przeanalizowaniu osoby początkujące nie będą miały problemu z zadaniami które wymagają użycia tych wiadomości.
Budowa wyrażenia regularnego
Poniżej zamieszczam podstawowe składniki – po więcej i bardziej szczegółowe zapraszam do dokumentacji :)
| (.*) | Dowolny ciąg znaków |
| (.*?) | Dowolny najkrótszy ciąg znaków |
| ([0-9]*) | Dowolny ciąg cyfr |
| ([0-9]*?) | Dowolny najkrótszy ciąg cyfr |
| ([a-zA-Z]*?) | Dowolny najkrótszy ciąg znaków malych i wielkich |
| ([0-9]{2,4}) | Dwie lub 4 cyfry |
Przykład
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <? function pr($a, $b, $c){ return preg_replace($a, $b, $c); } $toPregReplace = array( 'http://example.com' => array('/http:\/\/(.*?)\.(.*)/', '$1'), 'http://example.net.com' => array('/http:\/\/(.*?)\.(.*)/', '$1'), 'http://example.com/page/subpage/title' => array('/(.*)\/(.*?)/', '$2'), '<a href="blablabal" onclick="OPEN(\'http://example.com\');return false">ascasc</a>' => array('/<a(.*)?onclick="(.*?)"(.*)/', '$2'), '<a href="blablabal" onclick="OPEN(\'http://example.com\');return false">ascasc2</a>' => array('/<a(.*)?onclick="OPEN\((.*?)\)(.*?)"(.*)/', '$2'), '<a href="blablabal" onclick="OPEN(\'http://example.com\');return false">ascasc3</a>' => array('/(.*)?onclick="(.*?)\'(http:\/\/.*?)\'(.*)"(.*)/', '$3'), 'text{link{alert}}text' => array('/(.*)?{(.*?){(.*)}}(.*)?/', 'onclick="alert($3);">$2'), '01-blablabal-05_45_12.mp3' => array('/([0-9]*)(.*?)([0-9_]*)\.(.*)/', '$1_$3'), '01_blablabal_05_45_12.mp3' => array('/([0-9]*)(.*?)(_*)?([0-9_]*)\.(.*)/', '$1_$4'), '34573645/blablabal____05_45_12.mp3' => array('/([0-9]*)(.*?)(_*)?([0-9_]*)\.(.*)/', '$1_$4'), '34573645/blablabal__|__05_45_12.mp3' => array('/([0-9]*)(.*?)(_*)?([0-9_]*)\.(.*)/', '$1_$4'), ); echo '<table border="1">'; $i=0; foreach($toPregReplace as $k => $v){ echo '<tr>'; echo '<td>'.++$i.'</td>'; echo '<td>'.htmlspecialchars($k).'</td>'; echo '<td>'.htmlspecialchars($v[0])."</td>"; echo '<td>'.htmlspecialchars($v[1])."</td>"; echo '<td>'.pr($v[0], $v[1], $k).'</td>'; echo '<td><pre>'; preg_match($v[0], $k, $matches); foreach($matches as $k2=>$v2){ echo htmlspecialchars($k2)." => ".htmlspecialchars($v2)."<br>"; } echo '</pre></td>'; echo '</tr>'; } echo '</table>'; ?> |
Wynik
Powyższy skrypt powinien generować tabelkę, prezentuje ona jakieś stringi, wyrażenia regularne i efekt działania. Szczególnie polecam przyjrzeć się przykładom 9,10,11 – tutaj jest widoczna potęga wyrażeń i ich przewaga nad innymi metodami (np explode, impolode, str_replace).
Podsumowanie
Pomimo iż wyrażeń regularnych nie używa się zbyt często, bardzo warto je znać, bo w sytuacji kiedy jest możliwość ich użycia możemy zaoszczędzić wiele czasu :).
Tagi: php
1 Od niedawna maca php 2008-09-12 02:04:26
Jak ja /\/iecierpie tych \/\/ago/\/ikó\/\/, czy o/\/i podur/\/ieli do końca z tym w php?
2 maciek 2009-05-13 18:03:40
Świetny artykuł, wykorzystałem dużo z niego przy robieniu mojej strony.
3 ktoś 2009-05-26 16:11:50
Ten, co od niedawna maca php najwyraźniej nie rozumie, że standard RegExp jest rzeczą niezależną od PHP (no prawie) i twórcy PHP nie mają wpływu na konieczność używania „wagoników”.
Co do artykułu, to jest niezły, znalazłem tylko błąd w opisie:
([0-9]{2,4}) Dwie lub 4 cyfry
Powinno chyba być „Od 2 do 4 cyfr”.
4 ktoś 2009-05-26 16:20:11
Nie zauważyłem wcześniej, ale zapis tych wyrażeń też chyba nie jest poprawny:
([0-9]*?) Dowolny najkrótszy ciąg cyfr
([a-zA-Z]*?) Dowolny najkrótszy ciąg znaków malych i wielkich
W ogóle kombinacja *? nie ma sensu. I co to znaczy „dowolny najkrótszy ciąg”? Moim zdaniem to jest dokładnie 1 znak, czyli powinno być tak:
([0-9])
([a-zA-Z])
Ewentualnie:
([0-9]?)
([a-zA-Z]?)
Ale w tym przypadku też ma to mało sensu, bo „?” oznacza 0 lub 1 wystąpienie poprzedzającego znaku/wyrażenia. I co wtedy? Wyrażenie złapie ciąg znaków o zerowej długości?
5 Anonim 2009-08-03 21:33:15
*? jest jak najbardziej poprawny jest wersję niezachłanną kwantyfikatora * (zachłannego) podobnie jak +? jest odpowiednikiem +
6 kredytator 2010-12-16 04:55:18
http://www.kredytator.pl tanie kredyty i pozyczki