Tester Wyrażeń Regularnych
Testuj wyrażenia regularne na tekście i podświetl wszystkie dopasowania
Wzór
Łańcuch testowy
Czym jest wyrażenie regularne?
Wyrażenie regularne (regex lub regexp) to ciąg znaków definiujący wzorzec wyszukiwania. Testery regex pozwalają napisać wzorzec, uruchomić go na przykładowym tekście i zobaczyć wszystkie dopasowania podświetlone w czasie rzeczywistym. Koncepcja sięga pracy matematyka Stephena Kleene'ego nad językami regularnymi w latach 50. XX wieku, a Ken Thompson wbudował pierwszy silnik regex do edytora tekstu QED w 1968 roku.
Silnik regex czyta wzorzec od lewej do prawej, konsumując kolejne znaki wejściowe podczas dopasowywania. Stosuje nawracanie (backtracking), gdy częściowe dopasowanie zawodzi: silnik cofa się i próbuje alternatywnych ścieżek przez wzorzec. Niektóre silniki (jak RE2 używany w Go) całkowicie unikają nawracania, konwertując wzorce na deterministyczne automaty skończone (DFA), co gwarantuje liniowy czas dopasowania kosztem braku obsługi funkcji takich jak odwołania wsteczne.
Składnia regex jest luźno ustandaryzowana. PCRE (Perl Compatible Regular Expressions) to najczęściej stosowana odmiana, obsługiwana przez PHP, moduł re w Pythonie i JavaScript z drobnymi różnicami. POSIX definiuje bardziej ograniczoną składnię używaną przez grep i sed. Różnice mają znaczenie przy przenoszeniu wzorców między językami: asercja lookahead działająca w JavaScript może w ogóle nie skompilować się w silniku RE2 używanym przez Go.
Dlaczego warto używać testera regex online?
Pisanie regex w pliku kodu oznacza zapisywanie, uruchamianie i sprawdzanie wyniku za każdym razem, gdy zmieniasz wzorzec. Tester regex w przeglądarce skraca tę pętlę zwrotną do zera: piszesz i od razu widzisz dopasowania.
Zastosowania testera regex
Skrócony przewodnik po składni regex
Poniższa tabela obejmuje najczęściej używane tokeny regex. Działają one w JavaScript, Pythonie, Go, PHP i większości silników zgodnych z PCRE. Rozszerzenia specyficzne dla danego języka (takie jak warunkowe wzorce Pythona lub nazwane grupy JavaScript ze składnią \k) są opisane w sekcji z przykładami kodu.
| Wzorzec | Nazwa | Opis |
|---|---|---|
| . | Any character | Matches any single character except newline (unless s flag is set) |
| \d | Digit | Matches [0-9] |
| \w | Word character | Matches [a-zA-Z0-9_] |
| \s | Whitespace | Matches space, tab, newline, carriage return, form feed |
| \b | Word boundary | Matches the position between a word character and a non-word character |
| ^ | Start of string/line | Matches the start of the input; with m flag, matches start of each line |
| $ | End of string/line | Matches the end of the input; with m flag, matches end of each line |
| * | Zero or more | Matches the preceding token 0 or more times (greedy) |
| + | One or more | Matches the preceding token 1 or more times (greedy) |
| ? | Optional | Matches the preceding token 0 or 1 time |
| {n,m} | Quantifier range | Matches the preceding token between n and m times |
| () | Capturing group | Groups tokens and captures the matched text for back-references |
| (?:) | Non-capturing group | Groups tokens without capturing the matched text |
| (?=) | Positive lookahead | Matches a position followed by the given pattern, without consuming it |
| (?<=) | Positive lookbehind | Matches a position preceded by the given pattern, without consuming it |
| [abc] | Character class | Matches any one of the characters inside the brackets |
| [^abc] | Negated class | Matches any character not inside the brackets |
| | | Alternation | Matches the expression before or after the pipe |
Flagi regex — wyjaśnienie
Flagi (zwane też modyfikatorami) zmieniają sposób, w jaki silnik przetwarza wzorzec. W JavaScript dodajesz je po zamykającym ukośniku: /pattern/gi. W Pythonie przekazujesz je jako drugi argument: re.findall(pattern, text, re.IGNORECASE | re.MULTILINE). Nie wszystkie flagi są dostępne w każdym języku.
| Flaga | Nazwa | Zachowanie |
|---|---|---|
| g | Global | Find all matches, not just the first one |
| i | Case-insensitive | Letters match both uppercase and lowercase |
| m | Multiline | ^ and $ match start/end of each line, not just the whole string |
| s | Dot-all | . matches newline characters as well |
| u | Unicode | Treat the pattern and subject as a Unicode string; enables \u{FFFF} syntax |
| y | Sticky | Matches only from the lastIndex position in the target string |
Przykłady kodu
Działające przykłady regex w JavaScript, Pythonie, Go i wierszu poleceń. Każdy przykład pokazuje konstruowanie wzorca, wyodrębnianie dopasowań i wynik.
// Match all email addresses in a string
const text = 'Contact us at support@example.com or sales@example.com'
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
const matches = text.matchAll(emailRegex)
for (const match of matches) {
console.log(match[0], 'at index', match.index)
}
// → "support@example.com" at index 14
// → "sales@example.com" at index 37
// Named capture groups (ES2018+)
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
const result = '2026-03-30'.match(dateRegex)
console.log(result.groups)
// → { year: "2026", month: "03", day: "30" }
// Replace with a callback
'hello world'.replace(/\b\w/g, c => c.toUpperCase())
// → "Hello World"import re
# Find all IPv4 addresses
text = 'Server 192.168.1.1 responded, fallback to 10.0.0.255'
pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
matches = re.findall(pattern, text)
print(matches) # → ['192.168.1.1', '10.0.0.255']
# Named groups and match objects
date_pattern = r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})'
m = re.search(date_pattern, 'Released on 2026-03-30')
if m:
print(m.group('year')) # → '2026'
print(m.group('month')) # → '03'
# Compile for repeated use (faster in loops)
compiled = re.compile(r'\b[A-Z][a-z]+\b')
words = compiled.findall('Hello World Foo bar')
print(words) # → ['Hello', 'World', 'Foo']package main
import (
"fmt"
"regexp"
)
func main() {
// Find all matches
re := regexp.MustCompile(`\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b`)
text := "Contact support@example.com or sales@example.com"
matches := re.FindAllString(text, -1)
fmt.Println(matches)
// → [support@example.com sales@example.com]
// Named capture groups
dateRe := regexp.MustCompile(`(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})`)
match := dateRe.FindStringSubmatch("2026-03-30")
for i, name := range dateRe.SubexpNames() {
if name != "" {
fmt.Printf("%s: %s\n", name, match[i])
}
}
// → year: 2026
// → month: 03
// → day: 30
// Replace with a function
result := re.ReplaceAllStringFunc(text, func(s string) string {
return "[REDACTED]"
})
fmt.Println(result)
// → Contact [REDACTED] or [REDACTED]
}# Find lines matching an IP address pattern
grep -E '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b' access.log
# Extract email addresses from a file
grep -oE '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' contacts.txt
# Replace dates from YYYY-MM-DD to DD/MM/YYYY using sed
echo "2026-03-30" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/'
# → 30/03/2026
# Count matches per file in a directory
grep -rcE 'TODO|FIXME|HACK' src/
# → src/main.js:3
# → src/utils.js:1