Formularz odrzuca poprawny adres e-mail, wyszukiwarka nie znajduje numeru zamówienia, a filtr tekstu przepuszcza dane w złym formacie? W takich sytuacjach wyrażenia regularne pozwalają opisać wzorzec znaków i szybko sprawdzić, czy konkretny tekst do niego pasuje. Pokażę, jak działają, z jakich elementów się składają, jak używać ich w JavaScript oraz gdzie kończy się ich praktyczna użyteczność.
Najważniejsze zasady pracy ze wzorcami tekstu
- Wzorzec opisuje, jakie znaki i w jakiej kolejności mogą pojawić się w tekście.
- Znaki ^ i $ pozwalają sprawdzać początek oraz koniec całego ciągu.
- Klasy znaków, takie jak \d i [A-Z], skracają zapis często powtarzających się reguł.
- W JavaScript najczęściej korzysta się z metod test(), match() i replace().
- Regex sprawdza format danych, ale nie potwierdza, że dane są prawdziwe lub faktycznie istnieją.
Czym jest wzorzec tekstu i kiedy naprawdę pomaga
Regex, czyli wyrażenie opisujące układ znaków, działa jak mały filtr. Zamiast ręcznie analizować każdy znak, definiuję regułę, a silnik dopasowania sprawdza, czy tekst ją spełnia. Dzięki temu mogę znaleźć wszystkie liczby w akapicie, wyłuskać kod pocztowy albo sprawdzić podstawowy format adresu e-mail.
Przykładowo wzorzec \d+ oznacza jedną lub więcej cyfr. Dopasuje więc zarówno „7”, jak i „2026”, ale nie znajdzie liter ani pustego fragmentu. To ważne rozróżnienie, ponieważ regex nie „rozumie” znaczenia danych. Rozpoznaje wyłącznie ich zapis.
Najlepiej traktuję tę technikę jako narzędzie do lokalnego sprawdzania tekstu. Świetnie nadaje się do walidacji prostych pól, wyszukiwania fragmentów i zamiany powtarzalnych elementów. Nie powinna jednak zastępować parsera JSON, walidatora adresów URL czy logiki biznesowej, gdy reguły stają się złożone.
Przykład z codziennego programowania webowego jest prosty. Z pola formularza pobieram numer telefonu, usuwam zbędne spacje, a potem sprawdzam, czy pozostały ciąg zawiera wyłącznie dozwolone znaki. Samo dopasowanie nie gwarantuje jeszcze, że numer jest aktywny, ale skutecznie odrzuca oczywiste błędy.

Najważniejsze elementy składni bez zapamiętywania wszystkiego naraz
Na początku składnia wygląda jak przypadkowy zestaw ukośników i nawiasów. W praktyce wystarczy opanować kilka grup symboli. Poniższa tabela obejmuje elementy, po które sięgam najczęściej.
| Element | Znaczenie | Przykład |
|---|---|---|
. |
Dowolny pojedynczy znak |
k.t dopasuje „kot” i „kit” |
\d |
Cyfra |
\d{4} znajdzie cztery cyfry |
\w |
Znak słowa, zwykle litera, cyfra lub podkreślenie |
\w+ dopasuje pojedynczy wyraz bez spacji |
\s |
Biały znak, na przykład spacja lub tabulator |
\s+ znajdzie jedną lub więcej przerw |
[abc] |
Jeden znak z podanego zbioru |
[aeiou] dopasuje samogłoskę |
[^abc] |
Jeden znak spoza zbioru |
[^0-9] dopasuje znak niebędący cyfrą |
+ |
Co najmniej jedno powtórzenie |
a+ znajdzie „a”, „aa” i „aaa” |
* |
Zero lub więcej powtórzeń |
\d* pasuje także do pustego fragmentu |
? |
Zero lub jedno wystąpienie |
https? dopasuje „http” i „https” |
{m,n} |
Od m do n powtórzeń |
\d{2,3} znajdzie dwie albo trzy cyfry |
^ $ |
Początek i koniec tekstu |
^\d{5}$ wymaga dokładnie pięciu cyfr |
Dużą różnicę robią kotwice. Wzorzec \d{5} może znaleźć pięć cyfr w środku dłuższego tekstu, natomiast ^\d{5}$ wymaga, aby cały tekst składał się dokładnie z pięciu cyfr. To jeden z najczęstszych momentów, w których początkujący otrzymują wynik pozornie poprawny, ale zbyt luźny.
Przydatne są też grupy i alternatywy. Nawias () łączy fragmenty w całość, a znak | oznacza wybór. Wzorzec (jpg|png|webp) sprawdza trzy dozwolone rozszerzenia, choć przy plikach przesyłanych przez użytkownika sama kontrola nazwy nadal nie wystarcza do zapewnienia bezpieczeństwa.
Jak używać wzorców w JavaScript
W JavaScript mogę zapisać regułę jako literał, na przykład /^\d{5}$/, albo utworzyć obiekt RegExp. Pierwszy zapis jest czytelniejszy przy stałych wzorcach, drugi przydaje się wtedy, gdy reguła powstaje dynamicznie z danych programu.
const kod = /^\d{2}-\d{3}$/;
console.log(kod.test("00-001")); // true
console.log(kod.test("00001")); // false
Metoda test() zwraca wartość logiczną, więc dobrze pasuje do walidacji. Gdy chcę pobrać znaleziony fragment, używam match(). Do zamiany dopasowanych elementów służy replace(), na przykład przy normalizowaniu nadmiarowych spacji.
const tekst = "Cena: 19,99 zł, rabat: 5%";
const liczby = tekst.match(/\d+(?:[,.]\d+)?/g);
console.log(liczby); // ["19,99", "5"]
Flaga g oznacza wyszukiwanie wszystkich dopasowań, a i ignorowanie wielkości liter. Flaga m zmienia działanie kotwic w tekście wieloliniowym, natomiast u pomaga poprawnie pracować z pełnym zakresem znaków Unicode. Nie dodaję flag automatycznie. Każda powinna wynikać z konkretnej potrzeby, bo zmienia sposób działania wzorca.
W kodzie aplikacji warto oddzielić sprawdzenie danych od komunikatu dla użytkownika. Regex może odpowiedzieć „nie pasuje”, ale dopiero logika formularza powinna wyjaśnić, że trzeba podać kod w formacie „12-345”. Taki podział ułatwia testowanie i sprawia, że reguły nie zaczynają pełnić zbyt wielu funkcji naraz.
Praktyczne wzorce dla formularzy i tekstu
Numer telefonu
Prosty wzorzec dla polskiego numeru zapisanego jako dziewięć cyfr może wyglądać tak:
/^\d{9}$/
Jeśli aplikacja ma przyjmować także zapis z prefiksem kraju, regułę trzeba rozszerzyć. Nie próbowałbym jednak tworzyć jednego wzorca obsługującego każdy możliwy zapis telefonu na świecie. Lepsze rozwiązanie to normalizacja wejścia, a później osobna walidacja długości i dozwolonych znaków.
Adres e-mail
Do podstawowego sprawdzenia można użyć wzorca:
/^[^\s@]+@[^\s@]+\.[^\s@]+$/
Reguła wymaga znaku @, fragmentu domeny i kropki, ale nie dowodzi, że skrzynka istnieje. W praktyce poprawny proces obejmuje jeszcze wysłanie wiadomości z linkiem potwierdzającym. Bardzo rozbudowane wzorce próbujące odwzorować całą specyfikację adresów e-mail są trudne do utrzymania i często bardziej szkodzą czytelności niż pomagają.
Kod pocztowy
Polski kod pocztowy w typowym zapisie można sprawdzić tak:
/^\d{2}-\d{3}$/
Jeżeli formularz ma akceptować również zapis bez łącznika, można użyć opcjonalnego fragmentu -?. Trzeba jednak zdecydować, czy aplikacja później zapisze oba warianty w jednolitym formacie. Sam regex nie powinien ukrywać takich decyzji projektowych.
Przeczytaj również: Front-end vs. back-end: Co musisz wiedzieć?
Usuwanie zbędnych spacji
Do uporządkowania tekstu często wystarczy prosty zapis:
const wynik = tekst.trim().replace(/\s+/g, " ");
trim() usuwa białe znaki z początku i końca, a \s+ zamienia każdą serię spacji, tabulatorów lub znaków nowej linii na jedną spację. To drobny przykład, ale właśnie takie małe operacje najczęściej dają największą wartość w codziennej pracy.
Błędy, które psują dopasowanie
Pierwszy problem to pomijanie początku i końca tekstu. Wzorzec /\d{5}/ zaakceptuje fragment „12-345” albo „123456”, jeśli tylko znajdzie w nich pięć kolejnych cyfr. Dodanie kotwic wymusza pełną zgodność, ale trzeba pamiętać, że znaki nowej linii mogą zmienić zachowanie przy użyciu flagi m.
Drugi błąd to nieuwzględnianie znaków specjalnych. Kropka oznacza dowolny znak, więc jeśli chcę dopasować dosłowną kropkę, muszę zapisać \.. Podobnie nawias, znak plus czy pytajnik mają znaczenie składniowe i wymagają ucieczki, gdy występują jako zwykły tekst.
Niepokoi mnie też przesadne zaufanie do skrótów \w, \d i \s. Ich dokładne działanie zależy od silnika oraz flag, a zapis \w nie zawsze oznacza wszystkie litery używane w języku polskim. Gdy potrzebuję konkretnego alfabetu, jawna klasa znaków bywa bezpieczniejsza i bardziej zrozumiała.
Najpoważniejszym problemem mogą być kosztowne wzorce z wieloma zagnieżdżonymi kwantyfikatorami, na przykład (a+)+. Przy odpowiednio długim, niepasującym tekście silnik może wykonywać ogromną liczbę prób. W aplikacji obsługującej dane użytkownika testuję trudne przypadki i unikam konstrukcji, których działania nie potrafię jasno wyjaśnić.
Regex nie jest dobrym narzędziem do parsowania HTML, XML ani skomplikowanych struktur zagnieżdżonych. Do takich danych używam parsera, bo struktura dokumentu wymaga rozumienia relacji między elementami, a nie tylko dopasowania znaków.
Jak ćwiczyć, żeby regexy nie stały się czarną magią
Najskuteczniejsza metoda nauki to budowanie wzorca małymi krokami. Najpierw dopasowuję dosłowny tekst, potem dodaję klasę znaków, kwantyfikator i kotwice. Po każdej zmianie sprawdzam zarówno przykłady poprawne, jak i takie, które powinny zostać odrzucone.
- Zapisz kilka tekstów, które mają przejść walidację.
- Dodaj przypadki graniczne, na przykład pusty tekst, zbyt długi ciąg i dodatkową spację.
- Rozbij skomplikowany wzorzec na grupy i nazwij ich zadania komentarzem w kodzie.
- Sprawdź, czy prosty kod JavaScript nie będzie czytelniejszy niż kolejna warstwa składni.
- Przetestuj wydajność, jeśli tekst pochodzi bezpośrednio od użytkownika.
Moja praktyczna zasada jest prosta: używam regexu wtedy, gdy opisuje krótką i stabilną regułę. Gdy wzorzec zaczyna zajmować kilka linii, obsługuje wiele wyjątków albo wymaga długiego komentarza, zwykle lepiej zastąpić go kilkoma zwykłymi warunkami. Czytelność kodu jest ważniejsza niż satysfakcja z napisania jednej bardzo sprytnej linijki.
Opanowanie klas znaków, kwantyfikatorów, grup i kotwic wystarcza do większości zadań spotykanych na początku nauki programowania webowego. Później można świadomie wejść w lookaroundy, grupy nazwane i backreference, ale dopiero wtedy, gdy prostsze rozwiązania przestają wystarczać.