DEV Community

knighteq
knighteq

Posted on

1. Regex - podstawy

Co to jest wyrażenie regularne?

Wyrażenie regularne (regexp, regular expression) to wzorzec na postawie którego wyszukujemy określony zbiór znaków w danym ciągu tekstowym.

1. Proste wzorce

Wyrażenie regularne możemy pisać w różnoraki sposób, jednym z nich jest użycie prostych wzorców, czyli użycie jako wzorca konkretnego ciągu tekstowego.

regex: Ala ma kota.
string: Daniel ma psa, a Ala ma kota.

2. Znaki specjalne


Adnotacja: W przykładach pokazuję wyszukania z użyciem flagi \g (global). Więcej o niej w sekcji Flagi.

Sposób pierwszy możemy uzupełnić lub zastąpić sposobem drugim, czyli stworzyć wzorzec za pomocą znaków specjalnych. Oto one:

  • [xyz] - Zbiór znaków. Oznacza, że w ciągu tekstowym będziemy poszukiwać jeden ze znaków podanych między nawiasami kwadratowymi. Możemy dany zbiór opisać także jako zakres np. [a-c], oznacza on, że szukamy jednego ze znaków w zakresie tj. a, b lub c.

regex: [a-c0-3]
string: Eugeniusz walczył z 43 wojownikami.

  • [^xyz] - Negacja zbioru znaków. W danym ciągu tekstowym nie będziemy szukać żadnego z podanych znaków.

regex: [^0-3]
string: 1333,004

  • . - Dopasowuje każdy rodzaj znaku oprócz znaków łamania linii(\n, \r). Natomiast w zbiorze znaków traci swoją właściwość i dopasowuje wtedy znak kropki.

regex: [a-b.].
string: .c.e

regex: .
string: Eugeniusz

  • \d - Dopasowuje każdy znak liczbowy, jest równoznaczny z [0-9.

  • \D - Negacja znaku liczbowego, dopasowuje każdy znak który nie jest cyfrą. Równoznaczny z [^0-9].

  • \w - Dopasowuje każdy alfanumeryczny znak z podstawowego łacińskiego alfabetu. Równoznaczne z [A-Za-z0-9_].

  • \W - Negacja \w. Dopasowuje wszystko co nie jest znakiem z podstawowego łacińskiego alfabetu. Równoznaczne z [^A-Za-z0-9_].

  • \s - Dopasowuje pojedynczy biały znak(spacja, tab, enter).

  • \S - Dopasowuje każdy NIE biały znak.

Z powyższych opisów możemy dojść do wniosku, że skrócony opis wzorca zawierający wielką literę jest negacją wzorca napisanego z użyciem małej litery(\D - \d).

Więcej znaków specjalnych znajdziecie tutaj.

3. Grupowanie

Przy tworzeniu wyrażeń regularnych możemy się posługiwać grupowaniem, jest to zwłaszcza przydatne gdy oprócz pożądanego ciągu tekstowego, chcemy mieć także dostęp do jego poszczególnych składowych.

regex: (\d*) (\w*) (\d*)
string: 25 Stycznia 2015

match 0 - 25 Stycznia 2015
group 1 - 25
group 2 - Stycznia
group 3 - 2015

W tym przykładzie widzimy jak znalezione grupy są uwzględnione na kolejnych miejscach w tablicy.

const re = new RegExp(/(\d*) (\w*) (\d*)/);
const string = '25 Stycznia 2015';
const found = string.match(re);
console.log(found);

> ["25 Stycznia 2015", "25", "Stycznia", "2015"]
Enter fullscreen mode Exit fullscreen mode

3. Kwantyfikatory

W składni wyrażeń regularnych wykorzystujemy także kwantyfikatory, które określają nam ilość znaków jakie chcemy mieć dopasowane wykorzystując dany wzorzec. Oto ich lista z opisem jak je stosować:

  • x* - dopasowuje wzorzec x, zero lub więcej razy.

W przykładzie widzimy, że nie używając kwantyfikatora gwiazdki dopasuje nam się tylko jeden znak alfanumeryczny(w tym przypadku mała litera e).

regex: ([A-Z])\w*
string: Res

regex: ([A-Z])\w
string: Res

Natomiast poniżej możemy zauważyć, że mimo braku znaku z zakresu [a-e] pomiędzy literami A i l, to ciąg tekstowy Alm zostanie dopasowany, ze względu na to, że kwantyfikator gwiazdki dopuszcza brak występowania danego znaku.

regex: A[a-e]*lm
string: Almost done.

  • x+ - Dopasowuje wzorzec x, jeden lub więcej razy.

  • x? - dopasowuje wzorzec x, zero lub jeden raz.

  • x{n} - Dopasowuje wzorzec x "n" razy.

regex: \d{2}
string: 123

  • x{n,} - Dopasowuje wzorzec x minimum "n" razy.

  • x{n,m} - Dopasowuje wzorzec x minimum "n" razy, ale nie więcej niż "m" razy.

4. Podstawowe asercje

Asercje w wyrażeniach regularnych odpowiadają za "granice", czyli początki i końce linii oraz słów, na ich bazie możemy ustalić w którym miejscu dopasowanie ma mieć miejsce(na początku ciągu tekstowego, na jego końcu, po danym znaku lub przed danym znakiem). Typy asercji:

  • ^ - Dopasowuje początek ciągu tekstowego.
  • $ - Dopasowuje koniec ciągu tekstowego.

regex: ^\d*
string: 481 234 233

regex: \d*$
string: 481 234 233

  • \b - Granica ciągu tekstowego o długości zerowej. Dopasowuje pozycję między znakiem alfanumerycznym(\w), a negacją znaku alfanumerycznego(\W).

regex: \b\d{3}\b
string: 4813 234 2334

W podanym przykładzie nie zostaną dopasowane inne liczby niż 234(spacja nie jest znakiem alfanumerycznym w rozumieniu wyrażeń regularnych, więc zostaje dopasowana jako granica dopasowanego ciągu tekstowego), ponieważ w ciągu 4183, jest znak liczbowy(4), a wzorzec wymaga znaku niealfanumerycznego, tak też jest w związku z liczbą 2334.

Podam kolejny przykład, bardziej skomplikowany:

regex: \bcat\b
string: The cat scattered.
string: The$cat$scattered.

Słowo cat zostanie dopasowane gdy jest pomiędzy dwoma spacjami, natomiast już nie jeżeli jest w słowie s*cat*tered. Zostanie również dopasowane pomiędzy znakami dolara.
Dlaczego tak jest? Otóż zarówno spacja jak i znak $ nie są znakami alfanumerycznymi lub znakiem podkreślenia(który jest wyjątkiem), więc nie stanowią części słowa cat.

Głównym zadaniem asercji \b jest właśnie ustanowienie granicy rozpoczęcia lub zakończenia danego słowa. Możemy powiedzieć, że chcemy, żeby dane słowo było osobnym bytem, a nie częścią wyrazu.

  • \B - Dopasowuje pozycję, która nie jest granicą słowa.

regex: \B.*
string: noon

regex: s\B
string: sells

W tym przypadku nie zostanie dopasowany ostatni znak s, ponieważ tuż po nim mamy naturalną granicę słowa - spację.

5. Flagi

Wyrażenia regularne posiadają flagi, które możemy użyć aby rozszerzyć ich funkcjonalność, można je używać pojedynczo lub łącznie, kolejność zapisu nie ma znaczenia.

  • g - Globalne wyszukiwanie, warunkuje, że w danym ciągu tekstowym będą znalezione wszystkie możliwe dopasowania. Metoda działania opiera się na tym, że po pierwszym dopasowaniu nie następuje koniec działania programu, ale rozpoczyna się kolejne wyszukiwanie od końca poprzedniego dopasowania.

  • i - Case-insensitive, flaga warunkująca, że wyszukujemy nie zwracając uwagę na wielkość znaków.

  • m - Użycie definiuje, że asercje ^ i $, działają na bazie nowych linii, a nie całości ciągu tekstowego.

regex: /^\d{3}$/mg
string:
123
334

Więcej o flagach możecie przeczytać tutaj.

W kolejnym artykule opiszę użycie referencji zwrotnych, lookahead, lookbehind oraz pozostałych możliwości grupowań.

Top comments (0)