Wyszukiwanie - wyrażenia regularne

Pająk w narzędziu rozszerzonego wyszukiwania i zamiany oraz w narzędziu wyszukiwania tekstu pozwala na korzystanie z wyrażeń regularnych (ang. regular expressions).

Wyrażenia regularne to specjalne ciągi znaków stanowiące reguły lub wzorce, które pozwalają sprawdzić czy wyszukiwany tekst pasuje do ustalonego wzorca. Specjalne metaznaki pozwalają na przykład na określenie, że poszukiwany ciąg znaków musi występować na początku lub końcu linii, zawierać określoną liczbę powtórzeń wybranych znaków, itp.

Wyrażenia regularne dla początkujących wyglądają na skomplikowane, ale tak naprawdę są one zazwyczaj dość proste, poręczne i bardzo użyteczne.

Proste dopasowanie

Każdy pojedynczy znak odpowiada sobie samemu dopóki nie jest on metaznakiem o znaczeniu specjalnym, opisanym poniżej.

Grupa znaków odpowiada grupie znaków w docelowym ciągu znaków, a zatem np. tekst łubudu odpowiadać będzie ciągowi łubudu w docelowym ciągu.

Możesz spowodować, że znaki, które normalnie funkcjonują jako metaznaki lub sekwencje ucieczki (ang. escape sequences) będą interpretowane jako zwykłe znaki poprzez poprzedzenie ich znakiem odwrotnego ukośnika \. Na przykład metaznak ^ pasuje do każdego ciągu znaków zaczynającego się na początku linii. Jednakże ciąg \^ odpowiada znakowi ^ w tym ciągu, ciąg \\ odpowiada znakowi \, itd.

Przykłady:

łubuduodpowiada ciągowi łubudu
\^ŁuBuDuodpowiada ^ŁuBuDu

Sekwencje ucieczki

Poszczególne znaki mogą być cytowane poprzez użycie sekwencji ucieczki, której składnia przypomina tę znaną np. z języka C lub Perl. Na przykład \n oznacza nową linię, \t oznacza znak TAB, itd. Bardziej ogólna konstrukcja to \xnn, gdzie nn to ciąg szesnastkowych cyfr odpowiada znakowi, którego kod ASCII odpowiada wartości nn. Dla znaków Unicode można używać \x{nnnn} gdzie nnnn to jedna lub więcej cyfr szesnastkowych.

\xnnznak o kodzie ASCII nn
\x{nnnn}znak o kodzie nnnn (jeden bajt dla tekstu ASCII, dwa bajty dla znaków Unicode)
\tznak TAB (HT/TAB), to samo co \x09
\nnowa linia (NL), to samo co \x0a
\rpowrót karetki (CR), to samo co \x0d
\fform feed (FF), to samo co \x0c
\aalarm (BEL), to samo co \x07
\eescape (ESC), to samo co \x1b

Przykłady:

łubudu\x20trachodpowiada ciągowi łubudu trach (znak spacji pomiędzy)
\tłubuduodpowiada ciągowi łubudu poprzedzonemu znakiem TAB

Klasy znaków

Możesz określić klasę znaków poprzez zawarcie listy znaków w nawiasach kwadratowych [], które powodują dopasowanie do któregokolwiek znaku z listy w nawiasach.

Jeśli pierwszy znak po [ jest znakiem ^, klasa odpowiada znakom, które są poza nią. Jest to zaprzeczenie listy znaków obecnych w klasie.

Przykłady:

łubu[cdf]uznajduje ciągi łubucu, łubudu, łubufu, ale nie znajduje ciągów łubuau, łububu, łubueu, etc.
łubu[^cdf]uznajduje ciągi znaków np. łubuau, łububu, łubueu, itd, ale nie znajduje łubucu, łubudu, łubufu.

Na liście możesz użyć znaku -, aby określić zakres znaków, np. a-z reprezentuje zakres znaków między a a z włączając wszystkie pomiędzy.

Jeśli chcesz użyć znaku - jako członka klasy, czyli znaku wyszukiwanego, umieść go na początku listy lub oznacz znakiem odwrotnego ukośnika \. Jeśli chcesz wyszukiwać znak nawiasu ] możesz umieścić go również na początku listy lub użyć znaku backslash.

Przykłady:

[-az]odpowiada znakom a, z i -
[az-]odpowiada znakom a, z i -
[a\-z]odpowiada znakom a, z i -
[a-z]odpowiada wszystkim znakom od a do z
[\n-\x0D]odpowiada dowolnemu ze znaków o kodach #10, #11, #12, #13
[\d-t]odpowiada dowolnej cyfrze, znakowi - lub t
[]-a]odpowiada dowolnemu znakowi od ] do a

Metaznaki

Metaznaki to specjalne znaki, które są esencją wyrażeń regularnych. Występują różne typy metaznaków, które są opisane poniżej.

Metaznaki - separatory wierszy (lini)

^początek wiersza
$koniec wiersza
\Apoczątek tekstu
\Zkoniec tekstu
.dowolny znak w wierszu

Przykłady

^łubuduodpowiada ciągowi łubudu tylko jeśli znajduje się on na początku wiersza
łubudu$odpowiada znakowi łubudu tylko jeśli znajduje się on na końcu wiersza
^łubudu$odpowiada znakowi łubudu tylko jeśli jest on jedynym ciągiem w wierszu
łubu.uodpowiada ciągom łubuau, łububu, łubucu i tak dalej

Metaznak ^ domyślnie gwarantuje dopasowanie jedynie dla początku ciągu wejściowego, a $ dla końca. Wewnętrzne spearatory wierszy nie zostaną zatem dopasowane przez metaznaki ^ lub $.

Możesz jednak życzyć sobie, aby ciąg został potraktowany jako wieloliniowy taki, że ^ będzie pasował po dowolnym separatorze linii, a $ będzie pasował przed dowolnym separatorem linii. Możesz to zrobić za pomocą przełącznika /m.

Metaznaki \A oraz \Z działają tak jak ^ i $ z tym wyjątkiem, że nie będą odpowiadać wieloliniowym ciągom kiedy przełącznik /m jest użuywany, a ^ i $ odpowiadają każdemu wewnętrznemu separatorowi wierszy.

Metaznak . domyślnie odpowiada dowolnemu znakowi, ale jeśli wyłączysz przełącznik /s, wtedy metaznak . nie będzie odpowiadał wewnętrznym znakom separatorów wierszy.

Metaznaki - predefiniowane klasy

\wznak alfanumeryczny (włączając _)
\Wznak niealfanumeryczny
\dcyfra
\Dnie cyfra
\sdowolny odstęp (to samo co [ \t\n\r\f])
\Snie odstęp

Możesz używać \w, \d i \s wewnątrz własnych klas znaków.

Przykłady:

łubu\duodpowiada ciągom łubu1u, łubu6u i tak dalej, ale nie odpowiada ciągom łubudu, łubucu, itd
łubu[\w\s]uodpowiada ciągom łubudu, łubu u, łubuuu, ale nie odpowiada ciągom łubu1u, łubu=u, itd.

Metaznaki - iteratory

Po każdym elemencie wyrażenia regularnego może występować typ metaznaku zwany iteratorem. Używając iteratorów możesz określić ilość powtórzeń poprzedzającego znaku, metaznaku lub podwyrażenia w ciągu.

*zero lub więcej, podobne do {0,} (greedy)
+jeden lub więcej, podobne do {1,} (greedy)
?zero lub jeden, podobne do {0,1} (greedy)
{n}dokładnie n razy (greedy)
{n,}co najmniej n razy (greedy)
{n,m}przynajmniej n razy, ale nie więcej niż m razy (greedy)
*?zero lub więcej, podobne do {0,}? (nie greedy)
+?jeden lub więcej, podobne do {1,}? (nie greedy)
??zero lub jeden, podobne do {0,1}? (nie greedy)
{n}?dokładnie n razy (nie greedy)
{n,}?przynajmniej n razy (nie greedy)
{n,m}?co najmniej n razy, ale nie więcej niż m razy (nie greedy)

A zatem jak widać, cyfry w klamrach o postaci {n,m} określają minimalną (n) i maksymalną (m) ilość powtórzeń, aby zaszło dopasowanie. Możesz zamiennie używać formy {n} zamiast {n,n} i pozwala to na dokładne dopasowanie do wskazanej ilości wystąpień. Forma {n,} pozwala natomiast na dopasowanie co najmniej n razy lub więcej. Nie ma limitu w określaniu rozmiaru wartości n ani m, ale duże wartości mogą spowodować większe zużycie pamięci i spowolnienie działania wyrażeń regularnych.

Jeśli nawias klamrowy występuje w innym kontekście, jest on traktowany jako zwykły znak.

Przykłady

łubu.*uodpowiada ciągom takim jak łubuau, łubuajhkjsd33j8dsu oraz łubuu, itd.
łubu.+uodpowiada ciągom takim jak łubuau, łubuajhkjsd33j8dsu, itd, ale nie łubuu
łubu.?uodpowiada ciągom takim jak łubuau, łububu i łubuu, ale nie łubualkj9u
łubua{2}uodpowiada ciągowi łubuaau
łubua{2,}uodpowiada ciągom takim jak łubuaau, łubuaau, łubuaaau, itd.
łubua{2,3}uodpowiada ciągom takim jak łubuaau lub łubuaaau, ale nie łubuaaaau

Należy się jeszcze objaśnienie dopisku greedy (pol. chciwy) i nie greedy użytych w wyliczeniu iteratorów. W skrócie greedy odpowiada tak wielu jak to tylko możliwe, a nie greedy tak niewielu jak to tylko możliwe. Dla przykładu b+ i b* zastosowane dla ciągu abbbbc zwrócą bbbb, b+? natomiast zwróci b, a b*? zwróci pusty ciąg. b{2,3}? zwróci bb, a b{2,3} zwróci bbb.

Wszystkie iteratory mogą być przełączane w tryb nie greedy za pomocą modyfikatora /g.

Metaznaki - alternatywy

Możesz wskazać grupę alternatyw dla dla wzoru używając | do rozdzielania grup tak, że np. łut|łup|łuk będzie pasować do któregokolwiek słowa łut, łup lub łuk w ciągu docelowym (tak samo zadziała łu(t|p|k)). Pierwsza alternatywa zawiera wszystko z ostatniego separatora wzorca ((, [ lub początek wzorca) aż do pierwszego znaku |, a ostatnia alternatywa zawiera wszystko od ostatniego znaku | do następnego separatora wzorca. Z tego powodu powszechną praktyką jest umieszczanie alternatyw w nawiasach, aby zminimalizować wątpliwości dotyczące ich początku i końca.

Alternatywy są dopasowywane od lewej do prawej, a więc pierwsza znaleziona alternatywa, dla której całe wyrażenie jest zgodne jest tą, która jest wybierana. Znaczy to, że alternatywy nie są zazwyczaj "greedy". Dla przykładu, kiedy porównywane jest foo|foot z baerfoot tylko foo będzie odpowiadało ze względu na to, że jest to pierwsza dopasowywana alternatywa, która udanie pasuje do porównywanego ciągu.

Należy również pamiętać, że | w nawiasach kwadratowych jest interpretowany jako normalny znak, a więc jeśli napiszesz [łuk|łup|łut] tak naprawdę szukasz wyrażenia [łukpt|].

Przykład: łuk(asz|iem) odpowiada dwóm ciągom: łukasz lub łukiem.

Metaznaki - podwyrażenia

Konstrukacja nawiasowa ( ... ) może być również używana do definiowania podwyrażeń regularnych. Podwyrażenia są numerowane w porządku od lewej do prawej zależnie od otwierających nawiasów. Pierwsze podwyrażenie ma numer 1 (cały wynik wyrażenia regularnego ma numer 0).

Przykłady:

(łubudu){8,10}odpowiada ciągom, które zawierają 8, 9 lub 10 wystąpień słowa łubudu.
łubu([0-9]|d+)uodpowiada ciągom łubu0u, łubu1u, łubudu, łubuddu, etc.

Metaznaki - referencje wsteczne

Metaznaki \1 do \9 są interpretowane jako referencje wsteczne. \ odpowiada poprzedniemu dopasowanemu podwyrważeniu #.

Przykłady:

(.)\1+odpowiada aaaa i cc.
(.+)\1+odpowiada również abab i 123123
'(["]?)(\d+)\1odpowiada "13" (w cudzysłowach) lub '4' (w apostrofach) lub 77 (bez cudzysłowu czy apostrofu), itd.

Modifykatory

Modyfikatory pozwalają na zmianę zachowania funkcji wyszukiwania wyrażeń regularnych.

Istnieje wiele sposobów na ustawienie modyfikatorów. Każdy z modyfikatorów może być zawarty w wyrażeniu regularnym używając konstrukcji (?...).

.
iWykonuje wyszukiwanie wzorca bez uwzględniania wielkości liter.
mTraktuje ciąg jako wieloliniowy tzn. zmienia sposób działania ^ oraz $ z dopasowania zawsze początku lub końca ciągu na początek lub koniec każdej linii gdziekolwiek wewnątrz ciągu.
sTraktuje ciąg jako pojedynczą linię tzn. zmienia działanie . na dopasowanie do dowolnych znaków, nawet separatorów linii, które normalnie nie zostałyby zakwalifikowane jako pasujące do wzorca.
gNie standardowy modyfikator. Wyłączenie tego modyfikatora powoduje, że wszystkie następne operatory zaczynają działać w trybie nie greedy. Jeśli więc modyfikator /g jest wyłączony, wtedy + działa jak +?, * jak *? itd.
xRozszerza wzorzec poprzez zezwolenie na odstępy i komentarze (wyjaśnienie poniżej).

Modyfikator /x wymaga trochę wyjaśnienia. Wskazuje on programowi, żeby odstępy, które są oznaczone znakiem backslash lub znajdują się wewnątrz klasy, były ignorowane. Możesz użyć tego modyfikatora do podzielenia wyrażeń regularnych na bardziej czytelne części. Znak # jest również traktowany jako metaznak oznaczający komentarz, np.:

(
(abc) # comment 1
| # Możesz używać spacji do komentawania w.r.
(efg) # comment 2
)

Oznacza to, że jeśli chcesz uwzględnić odstępy oraz znak # we wzorcu (poza klasą znaków, gdzie modyfikator /x ich nie dotyczy), musisz albo użyć znaku backslash do oznaczenia ich lub zakodować je za pomocą szesnastkowych lub ósemkowych wartości kodów znaków. Podsumowując, te własności pozwalają na uczynienie wyrażenia regularnego lepiej czytelnym.

Rozszerzenia z Perl

(?imsxr-imsxr)

Możesz używać ich wewnątrz wyrażeń regularnych w locie. Jeśli taka konstrukcja jest zawarta w podwyrażeniu, wpływa ona tylko na to podwyrażenie.

Przykłady:

(?i)Nowy-Rokodpowiada ciągom Nowy-rok oraz Nowy-Rok
(?i)Nowy-(?-i)Rokodpowiada ciągowi Nowy-Rok, ale nie odpowiada ciągowi Nowy-rok
(?i)(Nowy-)?Rokodpowiada ciągowi Nowy-rok oraz nowy-rok
((?i)Nowy-)?Rokodpowiada ciągowi nowy-Rok, ale nie odpowiada ciągowi nowy-rok

(?#text)

Komentarz, którego tekst jest ignorowany. Zauważ, że program zamyka komentarz tak szybko jak tylko napotka metaznak ), a więc nie ma możliwości, aby umieścić znak ) w komentarzu.

Używanie w polu Zamień na wyników wyszukiwania przez wyrażenia regularne

Bardzo często odnalezione frazy będziesz chciał użyć w polu Zamień na. W tym przypadku należy umieścić w tekście, który będzie wstawiony na miejsce odnalezionej frazy odpowiedni symbol, np. $1, $2, $0 (gdzie $1 oznacza pierwszy fragment dopasowany do wyrażenia, $2 drugi itd., a $0 oznacza całą dopasowaną frazę - wszystkie fragmenty)

Przykłady: Załóżmy, że w treści wielu dokumentów znajduje się m. in. tekst:

<a href="galeria_pierwsza.php">Galeria pierwsza</a>
<a href="galeria_druga.php">Galeria druga</a>
<a href="galeria_trzecia.php">Galeria trzecia</a>
<a href="https://ksiega.gosci.pl/index.php">Księga gości</a>

Jednak postanowiłeś przerobić cały serwis tak, by korzystał z PHP i należy poprawić wszystkie odsyłacze. Na pierwszy rzut oka najprościej byłoby po prostu zmienić wszędzie ciąg .html na .php. Jednak to nie jest dobry pomysł, gdyż zamienione zostanie również rozszerzenie w odsyłaczy do księgi gości. Dlatego należy skorzystać z możliwości wyrażeń regularnych w narzędziu Rozszerzonego wyszukiwania i zamiany.

W polu 'Znajdź' należy wprowadzić:

galeria_([a-z0-9]+){1}.html

Odszukane zostaną wszystkie ciągi zawierające 'galeria_', dalej ciąg małych liter bądź cyfr (cały taki podciąg będzie traktowany jako jedno wystąpienie gdyż został ujęty w nawias, za którym postawiono {1}) i na końcu rozszerzenie .html

W polu 'Zamień na' należy wprowadzić:

galeria_$1.php

Powyższy zapis oznacza, że odszukana fraza zostanie zamieniona na 'galeria_', dalej odszukany podciąg małych liter bądź cyfr (odpowiednio 'pierwsza', 'druga', 'trzecia') i rozszerzenie '.php'. Odsyłacz do księgi gośi pozostanie oczywiście niezmieniony.

Wynikiem będzie następująca treść w dokumentach:

<a href="galeria_pierwsza.php">Galeria pierwsza</a>
<a href="galeria_druga.php">Galeria druga</a>
<a href="galeria_trzecia.php">Galeria trzecia</a>
<a href="https://ksiega.gosci.pl/index.php">Księga gości</a>

Pokrewne tematy

Do góry