W praktyce hasło js match prowadzi do metody String.prototype.match(), czyli wygodnego sposobu na wyciąganie dopasowań z tekstu na podstawie wyrażeń regularnych. W tym artykule pokazuję, jak czytać wynik, kiedy użyć flagi g, czym match() różni się od search(), test(), exec() i matchAll(), oraz gdzie najłatwiej popełnić błąd przy pracy z regexami.
Najkrótsza odpowiedź brzmi tak
-
match()zwracanull, jeśli nic nie znajdzie, więc wynik trzeba obsłużyć bezpośrednio przed użyciem. - Bez flagi
gdostajesz pierwszy pełny match i grupy przechwytujące, zgtylko listę dopasowanych fragmentów. - Jeśli chcesz tylko sprawdzić, czy wzorzec istnieje, zazwyczaj lepsze będzie
test(). - Jeśli potrzebujesz indeksu pierwszego trafienia, sięgnij po
search(). - Gdy zależy Ci na wszystkich dopasowaniach razem z grupami, najwygodniejsze jest
matchAll().
Czym jest match() i kiedy ma sens
match() traktuję jako narzędzie do pracy z tekstem, gdy chcę szybko znaleźć albo wyciągnąć fragmenty pasujące do wzorca. To nie jest zwykłe wyszukiwanie po łańcuchu znaków, tylko dopasowanie oparte o wyrażenia regularne, więc metoda sprawdza się tam, gdzie sam prosty indexOf() już nie wystarcza.
Najczęściej używam jej do zadań takich jak wykrycie numeru faktury, wyciągnięcie adresu e-mail, znalezienie daty, kodu produktu albo wszystkich słów spełniających konkretny wzorzec. W takich sytuacjach regex daje mi kontrolę nad tym, co dokładnie ma zostać uznane za trafienie, a match() zamienia ten wzorzec na konkretny wynik.
Ważne jest też to, że metoda działa na obiekcie typu String, ale jej sens wychodzi dopiero wtedy, gdy podasz sensowny wzorzec. Dlatego w praktyce myślę o niej nie jako o „szukaniu słowa”, tylko jako o wydobywaniu danych z tekstu. To nastawienie od razu porządkuje pracę z nią i dobrze prowadzi do różnicy między wynikiem z flagą g i bez niej.
Jak czytać wynik z flagą g i bez niej
To właśnie tutaj większość osób myli się na początku. match() zwraca inną strukturę danych w zależności od tego, czy regex ma flagę g. Bez niej dostajesz pierwszy pełny match wraz z grupami przechwytującymi, a z nią listę wszystkich dopasowanych fragmentów, ale już bez grup.
| Wariant | Co zwraca | Kiedy to pasuje |
|---|---|---|
Bez g
|
Tablicę z pierwszym dopasowaniem, grupami, index, input i ewentualnie groups
|
Gdy potrzebujesz szczegółów pierwszego trafienia |
Z g
|
Tablicę samych dopasowanych fragmentów | Gdy chcesz zebrać wszystkie wystąpienia wzorca |
| Brak trafienia | null |
Gdy wzorzec nie występuje w tekście |
Przykład bez flagi g jest dobry wtedy, gdy chcę wiedzieć nie tylko co zostało znalezione, ale też jak wzorzec się rozbił na części:
const text = "Zamówienie: A-1024, status: opłacone";
const result = text.match(/([A-Z])-(\d+)/);
if (result) {
console.log(result[0]); // A-1024
console.log(result[1]); // A
console.log(result[2]); // 1024
console.log(result.index); // pozycja pierwszego trafienia
}
Jeśli dodam flagę g, dostanę już tylko listę wszystkich pasujących fragmentów. To wygodne przy wyciąganiu serii danych, na przykład wszystkich identyfikatorów, tagów albo słów pasujących do wzorca:
const text = "JS, CSS, HTML, JS";
const matches = text.match(/\b[A-Z]{2,4}\b/g);
console.log(matches); // ["JS", "CSS", "HTML", "JS"]
Warto zapamiętać prostą zasadę: bez g liczy się pojedynczy wynik i szczegóły, z g liczy się seria trafień. To rozróżnienie bardzo ułatwia dobranie właściwej metody w następnym kroku.
Jak rozwiązać najczęstsze zadania w praktyce
W codziennej pracy najważniejsze nie jest samo wywołanie metody, tylko to, czy wynik da się od razu sensownie wykorzystać. Poniżej pokazuję kilka scenariuszy, które najczęściej pojawiają się przy wyszukiwaniu w tekście.
Wyciąganie pierwszego dopasowania
Gdy potrzebuję tylko pierwszego trafienia, używam wzorca bez flagi g. To przydatne, kiedy chcę pobrać np. pierwszy kod zamówienia, pierwszą datę albo pierwszy numer telefonu z opisu.
const description = "Kontakt: 600123456, drugi numer: 501999888";
const found = description.match(/\b\d{9}\b/);
const phone = found ? found[0] : null;
console.log(phone); // 600123456
Taki zapis jest czytelny i bezpieczny, bo od razu zakłada, że dopasowanie może nie istnieć. W praktyce to dużo lepsze niż bezpośrednie odwoływanie się do found[0], które może skończyć się błędem przy braku trafienia.
Wyciąganie wielu dopasowań
Jeśli tekst zawiera kilka elementów do zebrania, wtedy włączam g. To naturalny wybór przy listach tagów, skrótach, numerach referencyjnych albo słowach spełniających określony warunek.
const tags = "frontend, backend, javascript, css, html";
const words = tags.match(/\b[a-z]+\b/gi);
console.log(words); // ["frontend", "backend", "javascript", "css", "html"]
Tu ważna jest jedna rzecz: zwracana tablica nie zawiera grup przechwytujących. Jeśli grupy są Ci potrzebne przy każdym elemencie, samo match() z flagą g zwykle nie wystarczy.
Przeczytaj również: JS defer - klucz do szybszej strony? Sprawdź, jak to działa!
Nazwane grupy przy bardziej czytelnych wzorcach
Gdy wzorzec robi się trochę bardziej złożony, nazwane grupy przechwytujące poprawiają czytelność. Nie muszę wtedy pamiętać, co oznacza grupa numer 1 albo 2, tylko odwołuję się do nazwy.
const code = "JS-2026";
const result = code.match(/(?JS)-(?\d{4})/);
if (result) {
console.log(result.groups.lang); // JS
console.log(result.groups.year); // 2026
}
To rozwiązanie szczególnie dobrze działa wtedy, gdy regex ma być utrzymywany przez dłuższy czas albo ma go dotykać więcej niż jedna osoba. Im mniej zgadywania, tym mniej błędów w przyszłości, a to prowadzi do wyboru właściwego narzędzia obok match().

Jak dobrać match(), matchAll(), search(), test() i exec()
Najlepiej myśleć o tych metodach jak o narzędziach do różnych zadań, a nie o zamiennikach. Wtedy decyzja robi się prosta: pytam najpierw, czy chcę tylko potwierdzić istnienie dopasowania, poznać jego pozycję, zebrać wszystkie trafienia, czy wyciągnąć też grupy.
| Metoda | Co zwraca | Najlepsze zastosowanie | Ograniczenie |
|---|---|---|---|
test() |
true albo false
|
Szybka walidacja, czy wzorzec istnieje | Nie daje samego dopasowania |
search() |
Indeks pierwszego trafienia albo -1
|
Gdy interesuje Cię pozycja dopasowania | Nie zwraca dopasowanej treści |
match() |
Pierwszy match z grupami albo lista wszystkich trafień bez grup | Gdy chcesz dopasować i od razu coś z wyniku odczytać | Zmienia strukturę wyniku zależnie od g
|
matchAll() |
Iterator wszystkich dopasowań z grupami | Gdy chcesz przejść po każdym trafieniu i zachować grupy | Wymaga regexu z flagą g
|
exec() |
Tablicę szczegółów dopasowania | Gdy potrzebujesz kontroli nad kolejnymi dopasowaniami i lastIndex
|
Jest bardziej niskopoziomowe i stanowe |
W praktyce wybieram test() do samej walidacji, search() do indeksu, match() do prostego wyciągania danych, a matchAll(), kiedy chcę wszystkie wyniki razem z grupami. exec() zostawiam sobie na bardziej techniczne przypadki, gdy zależy mi na precyzyjnej kontroli iteracji albo na pracy z lastIndex. To zestawienie dobrze pokazuje, dlaczego pytanie o „match w JS” rzadko dotyczy jednej metody, a częściej wyboru właściwego narzędzia.
Najczęstsze pułapki przy dopasowaniach
Największe problemy nie wynikają zwykle z samej metody, tylko z tego, jak napisany jest wzorzec i co zakładamy o wyniku. Poniżej zbieram błędy, które widzę najczęściej w kodzie początkujących i średniozaawansowanych.
-
Brak obsługi
null- jeśli nic nie pasuje,match()nie zwróci pustej tablicy, tylkonull. To trzeba sprawdzić przed użyciem wyniku. -
Oczekiwanie grup przy fladze
g- po włączeniu globalnego wyszukiwania dostajesz listę dopasowań, ale nie pełne dane z grup przechwytujących. - Nieucieczone znaki specjalne - kropka, plus, gwiazdka czy nawiasy mają w regexach specjalne znaczenie. Jeśli szukasz dosłownego tekstu, musisz je poprzedzić ukośnikiem.
- Przekazywanie zwykłego tekstu jako wzorca bez refleksji - jeśli wzorzec pochodzi z danych użytkownika, łatwo przypadkiem zamienić zwykły znak w metaznak.
-
Mylenie
match()zsearch()- jedno zwraca treść dopasowania, drugie indeks. To różnica praktyczna, nie kosmetyczna.
Dobry przykład to "123".match("1.3"). Wiele osób spodziewa się dopasowania tylko do dosłownego ciągu 1.3, a tymczasem kropka w regexie oznacza dowolny znak, więc wynik może być zaskakujący. Jeśli naprawdę chodzi o kropkę, trzeba ją zapisać jako 1\\.3.
console.log("123".match("1.3")); // ["123"]
console.log("123".match("1\\.3")); // null
Ten drobiazg dobrze pokazuje, że przy regexach liczy się nie tylko metoda, ale też precyzja samego wzorca. Gdy ten fragment jest opanowany, warto przejść do sposobu pisania dopasowań tak, żeby dało się je utrzymać w większym projekcie.
Jak pisać dopasowania, które da się utrzymać po miesiącu
Na większym projekcie nie wygrywa najbardziej sprytne wyrażenie regularne, tylko takie, które po czasie nadal da się odczytać bez zgadywania. Dlatego ja trzymam się kilku zasad: wzorce nazywam, gdy są złożone, nie upycham wszystkiego w jednym potwornym regexie i wybieram metodę zgodną z celem, zamiast „na wszelki wypadek” sięgać po najcięższe narzędzie.
Jeśli regex służy tylko do sprawdzenia poprawności, często lepiej wypada test(). Jeśli ma zwrócić konkretne fragmenty tekstu, wybieram match() albo matchAll(). Dzięki temu kod czyta się jak decyzję biznesową, a nie jak łamigłówkę techniczną. To szczególnie ważne, gdy dopasowania trafiają do formularzy, parserów prostych logów albo filtrów danych wejściowych.
Najbardziej praktyczna zasada, którą sobie zostawiam, brzmi tak: najpierw określ, co chcesz dostać na wyjściu, dopiero potem pisz wzorzec. Gdy odwrócisz tę kolejność, szybko kończysz z regexem, który działa tylko w jednym, idealnym scenariuszu. A w codziennym JavaScripcie najbardziej przydaje się kod, który jest prosty, przewidywalny i odporny na brak dopasowania.