Wyrażenia regularne (Regex) - kompendium praktyczne
Regex to rodzina języków wzorców, a nie jeden identyczny standard we wszystkich programach. Składnia grep/POSIX, JavaScript, Python i PCRE jest podobna, ale różni się szczegółami, dlatego przed użyciem zaawansowanych konstrukcji warto wiedzieć, jakiego engine używa dane narzędzie.
Powiązane tematy: Programowanie w shellu, Visual Studio Code, Vi, Vim, gVim i Neovim oraz Python.
1. Czym jest regex
Wyrażenie regularne opisuje wzorzec tekstu.
Przykłady zastosowań:
- wyszukiwanie,
- walidacja,
- zamiana,
- parsowanie prostych formatów,
- filtrowanie logów,
- praca w edytorze,
- grep, sed, JavaScript, Python.
Regex jest bardzo użyteczny, ale łatwo go nadużyć. Jeżeli format ma pełny parser, często lepiej użyć parsera.
2. Najprostszy wzorzec
Regex:
cat
pasuje do:
cat
concatenate
category
3. Znaki specjalne
Najczęstsze:
. dowolny znak
^ początek
$ koniec
* zero lub więcej
+ jeden lub więcej
? zero lub jeden
[] klasa znaków
() grupa
| alternatywa
\ escape
4. Kropka
a.c
pasuje do:
abc
a-c
a c
Jeśli chcesz dosłowną kropkę:
\.
5. Początek i koniec
^hello$
pasuje tylko do całego:
hello
Nie pasuje do:
hello world
say hello
6. Klasy znaków
[abc]
jeden z: a, b, c.
Zakres:
[a-z]
[A-Z]
[0-9]
Negacja:
[^0-9]
7. Skróty
Często:
\d cyfra
\w znak słowa
\s whitespace
Negacje:
\D
\W
\S
Znaczenie \w może się różnić zależnie od silnika i trybu Unicode.
8. Kwantyfikatory
a* 0+
a+ 1+
a? 0 lub 1
a{3} dokładnie 3
a{2,5} od 2 do 5
a{2,} co najmniej 2
9. Grupy
(ab)+
pasuje do:
ab
abab
ababab
10. Alternatywa
cat|dog
11. Grupowanie alternatywy
^(cat|dog)$
pasuje dokładnie do cat lub dog.
12. Grupy przechwytujące
(\d{4})-(\d{2})-(\d{2})
Dla:
2026-09-19
grupy:
1 = 2026
2 = 09
3 = 19
13. Grupa nieprzechwytująca
W wielu silnikach:
(?:abc)
Grupuje bez tworzenia numerowanej grupy.
14. Named groups
Przykład JavaScript:
(?<year>\d{4})-(?<month>\d{2})
Nazwane grupy poprawiają czytelność.
15. Greedy i lazy
Greedy:
".*"
Lazy:
".*?"
Dla:
"a" "b"
greedy może złapać całość, a lazy pierwszy najmniejszy fragment.
16. Lookahead
Positive:
foo(?=bar)
pasuje do foo, jeśli dalej jest bar.
Negative:
foo(?!bar)
17. Lookbehind
Jeżeli silnik wspiera:
(?<=prefix)\d+
Nie każdy silnik ma identyczne możliwości.
18. Flagi
Popularne:
i case-insensitive
m multiline
s dotall
g global
JavaScript:
const re = /error/gi;
19. JavaScript
Test:
const re = /^\d{4}-\d{2}-\d{2}$/;
console.log(re.test("2026-09-19"));
Match:
const result = "id=123".match(/\d+/);
Replace:
"hello world".replace(/world/, "regex");
20. Python
import re
if re.search(r"error", text, re.I):
print("found")
Raw strings r"..." ograniczają problem podwójnego escapowania.
21. grep
grep -E 'error|warning' app.log
Case-insensitive:
grep -Ei 'error|warning' app.log
22. sed
Zamiana:
sed -E 's/[0-9]+/NUMBER/g' file.txt
23. VS Code / Vim
Edytory potrafią wyszukiwać i zamieniać przy użyciu regex.
Przykład:
Znajdź:
foo([0-9]+)
Zamień:
bar$1
Składnia referencji do grup zależy od narzędzia.
24. Walidacja emaila
Nie próbuj odtwarzać całego RFC ogromnym regexem.
Praktyczna walidacja formularza powinna być rozsądna, a prawdziwym potwierdzeniem adresu jest np. wysłanie wiadomości weryfikacyjnej.
25. Regex a HTML
Nie używaj regexu jako pełnego parsera HTML.
HTML ma strukturę, nesting i wiele wyjątków.
Użyj parsera DOM.
26. Czytelność
Jeżeli regex robi się duży:
- dodaj komentarz,
- podziel problem,
- użyj named groups,
- rozważ parser.
27. Testowanie
Zawsze testuj:
- poprawne dane,
- błędne dane,
- pusty string,
- znaki Unicode,
- bardzo długie wejście.
28. ReDoS
Źle skonstruowane regexy mogą mieć bardzo kosztowny backtracking.
Nie uruchamiaj skomplikowanych wzorców na dowolnie długich danych użytkownika bez analizy.
29. Przykłady
IPv4 - prosty wzorzec składniowy:
^(\d{1,3}\.){3}\d{1,3}$
Uwaga: dopuszcza np. 999.999.999.999. Walidacja semantyczna wymaga dodatkowej logiki.
Slug:
^[a-z0-9]+(?:-[a-z0-9]+)*$
Prosty identyfikator:
^[A-Za-z_][A-Za-z0-9_]*$
30. Co trzeba umieć
- czytać klasy znaków,
- używać anchors,
- stosować kwantyfikatory,
- grupować,
- robić search/replace,
- rozumieć greedy/lazy,
- korzystać z regex w grep, JS i Pythonie,
- wiedzieć, kiedy regex nie jest dobrym narzędziem.
Źródła referencyjne
- POSIX regular expressions: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap09.html
- MDN regular expressions: https://developer.mozilla.org/docs/Web/JavaScript/Guide/Regular_expressions
- Python re: https://docs.python.org/3/library/re.html