Gdy trzeba podmienić fragment tekstu, usunąć niepotrzebne znaki albo ujednolicić dane wejściowe, metoda replace() w JavaScript zwykle jest najlepszym punktem wyjścia. Pokażę, jak działa, dlaczego domyślnie zmienia tylko pierwsze dopasowanie, kiedy użyć wyrażenia regularnego lub replaceAll() oraz jakie błędy najczęściej pojawiają się w praktycznym kodzie.
Najważniejsze zasady zamiany tekstu w JavaScript
-
replace()nie zmienia oryginalnego łańcucha, tylko zwraca nowy tekst. - Przy zwykłym stringu metoda podmienia domyślnie pierwsze dopasowanie.
- Do wszystkich wystąpień można użyć
replaceAll()albo wyrażenia regularnego z flagąg. - Drugi argument może być tekstem lub funkcją obliczającą zamianę.
- Najczęstsze pułapki to brak przypisania wyniku, wielkość liter i niepotrzebne użycie regexu.
Jak działa metoda replace()
Podstawowa składnia jest prosta. Na istniejącym tekście wywołuję replace(), przekazuję szukany fragment i wartość, która ma go zastąpić.
const message = "Cześć, Aniu!";
const updatedMessage = message.replace("Aniu", "Marku");
console.log(updatedMessage);
// Cześć, Marku!
Pierwszy argument określa wzorzec wyszukiwania, a drugi zawartość zastępczą. Wzorzec może być zwykłym tekstem albo wyrażeniem regularnym, czyli specjalnym zapisem pozwalającym opisać bardziej elastyczne dopasowanie.
Trzeba też pamiętać, że stringi w JavaScript są niemutowalne. Metoda nie nadpisuje zmiennej automatycznie, dlatego poniższy kod nie zmieni wartości text.
let text = "Stary tekst";
text.replace("Stary", "Nowy");
console.log(text);
// Stary tekst
Jeśli chcę zachować zmianę, przypisuję wynik z powrotem do zmiennej albo przekazuję go dalej.
text = text.replace("Stary", "Nowy");
console.log(text);
// Nowy tekst
Właśnie brak tego przypisania jest jednym z błędów, które widzę najczęściej u osób zaczynających pracę z JavaScriptem. Sam zwykle od razu zapisuję wynik do nowej stałej, gdy chcę uniknąć przypadkowego nadpisania danych wejściowych.
Pierwsze dopasowanie i wszystkie wystąpienia
Gdy jako pierwszy argument podam zwykły string, metoda podmieni tylko pierwszy znaleziony fragment.
const text = "kot, kot i jeszcze jeden kot";
const result = text.replace("kot", "pies");
console.log(result);
// pies, kot i jeszcze jeden kot
To zachowanie jest prawidłowe, choć na początku może wydawać się zaskakujące. Jeżeli chcesz zmienić każde wystąpienie, masz dwie czytelne możliwości.
Wyrażenie regularne z flagą g
const text = "kot, kot i jeszcze jeden kot";
const result = text.replace(/kot/g, "pies");
console.log(result);
// pies, pies i jeszcze jeden pies
Flaga g oznacza wyszukiwanie globalne, czyli obejmujące cały tekst. Można połączyć ją z flagą i, aby ignorować wielkość liter.
const text = "JavaScript, javascript i JAVASCRIPT";
const result = text.replace(/javascript/gi, "JS");
console.log(result);
// JS, JS i JS
Metoda replaceAll()
Jeśli zamieniasz dosłowny tekst i nie potrzebujesz możliwości regexu, często wybieram replaceAll(). Kod jasno komunikuje zamiar i nie wymaga pamiętania flagi g.
const text = "kot, kot i jeszcze jeden kot";
const result = text.replaceAll("kot", "pies");
console.log(result);
// pies, pies i jeszcze jeden pies
Różnica między metodami wygląda tak:
| Rozwiązanie | Zakres działania | Kiedy użyć |
|---|---|---|
replace("a", "b") |
Pierwsze dopasowanie | Gdy chcesz zmienić tylko jeden fragment |
replace(/a/g, "b") |
Wszystkie dopasowania regexu | Gdy potrzebujesz wzorca lub dodatkowych flag |
replaceAll("a", "b") |
Wszystkie identyczne fragmenty | Gdy zamiana ma być dosłowna i prosta |
Moja praktyczna zasada jest prosta: dla zwykłego tekstu wybieram replaceAll(), a regex zostawiam na sytuacje, w których rzeczywiście opisuje problem lepiej. Przy wyrażeniu regularnym z flagą g trzeba też uważać na szczególne znaki, takie jak kropka, nawias czy znak zapytania, bo mają one własne znaczenie.

Praktyczne przykłady użycia
Najprostsze zastosowania dotyczą formatowania tekstu, przygotowywania danych do wyświetlenia i usuwania niechcianych znaków. Poniżej są przykłady, które dobrze pokazują różne warianty tej samej metody.
Usuwanie znaków i spacji
const phone = "500-600-700";
const cleanPhone = phone.replaceAll("-", "");
console.log(cleanPhone);
// 500600700
Ten zapis sprawdza się przy prostym czyszczeniu danych, na przykład przed wysłaniem numeru telefonu do API. Nie należy jednak zakładać, że każdy numer można bezpiecznie oczyścić w ten sam sposób, ponieważ formaty danych mogą zależeć od kraju i wymagań konkretnego systemu.
Zamiana kilku rodzajów separatorów
const tags = "javascript, html; css | react";
const normalizedTags = tags.replace(/[,;|]/g, ",");
console.log(normalizedTags);
// javascript, html, css , react
Wyrażenie [,;|] oznacza dowolny jeden znak z podanego zbioru. Taki krok bywa przydatny przed użyciem split(","), choć w realnym projekcie zwykle warto też usunąć nadmiarowe spacje.
const tags = "javascript, html; css | react";
const normalizedTags = tags
.replace(/[,;|]/g, ",")
.split(",")
.map(tag => tag.trim());
console.log(normalizedTags);
// ["javascript", "html", "css", "react"]
Podmiana danych za pomocą funkcji
Drugi argument nie musi być stałym tekstem. Może nim być funkcja, która dla każdego dopasowania obliczy osobny wynik. To dobre rozwiązanie, gdy zamiana zależy od wartości znalezionego fragmentu.
const result = "Cena: 20 zł, rabat: 15 zł".replace(
/\d+/g,
number => String(Number(number) * 2)
);
console.log(result);
// Cena: 40 zł, rabat: 30 zł
Funkcja otrzymuje między innymi dopasowany tekst. Dzięki temu mogę go przekonwertować, sprawdzić albo przekształcić bez budowania kilku osobnych wyrażeń. Trzeba tylko pamiętać, że przykład z mnożeniem jest demonstracyjny, a prawdziwe ceny powinny być obsługiwane z uwzględnieniem waluty i dokładności obliczeń.
Wykorzystanie grup przechwytujących
Regex może podzielić dopasowanie na grupy, a wynik można złożyć w innej kolejności. Przykładowo format daty 2026-09-13 da się zmienić na zapis używany w polskich interfejsach.
const date = "2026-09-13";
const polishDate = date.replace(
/^(\d{4})-(\d{2})-(\d{2})$/,
"$3.$2.$1"
);
console.log(polishDate);
// 13.09.2026
Symbole $1, $2 i $3 odnoszą się do kolejnych grup w regexie. To wygodne, ale przy bardziej rozbudowanych wzorcach łatwo pomylić numer grupy, dlatego w większym kodzie preferuję funkcję zastępującą albo nazwane grupy.
Najczęstsze błędy i ograniczenia
Wielkość liter ma znaczenie
Zwykłe wyszukiwanie jest domyślnie wrażliwe na wielkość liter. Tekst "JavaScript" nie pasuje do "javascript".
const text = "JavaScript jest popularny";
console.log(text.replace("javascript", "JS"));
// JavaScript jest popularny
console.log(text.replace(/javascript/i, "JS"));
// JS jest popularny
Jeżeli dane pochodzą od użytkownika, warto wcześniej ustalić, czy wielkość liter ma znaczenie biznesowe. Dodanie flagi i wszędzie nie zawsze jest dobrym pomysłem, bo może ukryć różnice, które w danym przypadku powinny pozostać widoczne.
Regex nie jest zawsze lepszy
Regex daje dużą elastyczność, ale zwiększa złożoność kodu. Do zamiany dokładnego tekstu użycie zapisu /tekst/g jest często mniej czytelne niż zwykłe replaceAll("tekst", "...").
Ma to także znaczenie przy danych pochodzących od użytkownika. Wstawienie takiej wartości bezpośrednio do dynamicznie tworzonego regexu może spowodować, że znaki specjalne zaczną działać jak element wzorca, a nie jak zwykły tekst.
Przeczytaj również: Async vs Defer - Wybierz dobrze i przyspiesz swoją stronę!
replace() nie służy do bezpiecznego filtrowania HTML
Podmiana kilku znaków w ciągu nie jest pełnym mechanizmem ochrony przed wstrzyknięciem kodu. Nie traktuję więc konstrukcji typu text.replace("<", "<") jako uniwersalnego sanitizera, czyli narzędzia do bezpiecznego oczyszczania HTML.
Jeśli tekst ma trafić do strony, używam odpowiedniego kontekstu DOM, na przykład textContent, albo sprawdzonego narzędzia do sanitizacji. Prosty replace nie zastępuje ochrony aplikacji, szczególnie gdy dane pochodzą od innych osób.
Co wybrać zamiast replace()
Ta metoda jest bardzo uniwersalna, ale nie rozwiązuje każdego problemu z tekstem. Dobór narzędzia zależy od tego, czy zmieniasz jeden fragment, wszystkie wystąpienia, czy może strukturę całego tekstu.
| Potrzeba | Lepsze rozwiązanie | Dlaczego |
|---|---|---|
| Jedna prosta podmiana | replace() |
Krótki i czytelny zapis |
| Wszystkie identyczne fragmenty | replaceAll() |
Nie trzeba używać flagi g
|
| Złożony wzorzec |
replace() z regexem |
Możliwość użycia grup i flag |
| Rozdzielenie tekstu na elementy | split() |
Łatwiejsza praca z tablicą wartości |
| Zmiana formatu wielu elementów | map() |
Każdy element można przekształcić osobno |
Czasem widzę kod, który próbuje jednym długim regexem rozwiązać problem wymagający kilku prostych kroków. Zwykle lepiej rozdzielić operacje, nazwać pośrednie wyniki i dopiero potem sprawdzić rezultat. Czytelność wygrywa z jednowierszowym skrótem, zwłaszcza gdy kod będzie później rozwijany.
Mała checklista przed użyciem metody
- Sprawdź, czy chcesz zmienić pierwsze wystąpienie, czy wszystkie.
- Zdecyduj, czy szukany fragment jest zwykłym tekstem, czy wzorcem regex.
- Pamiętaj o przypisaniu wyniku, ponieważ stringi są niemutowalne.
- Zweryfikuj wielkość liter i możliwe spacje w danych wejściowych.
- Przetestuj przypadek, w którym tekst nie zawiera szukanego fragmentu.
- Nie używaj ręcznej podmiany jako zamiennika bezpiecznej sanitizacji HTML.
W prostym scenariuszu wystarczy zapamiętać dwa warianty. replace() służy najczęściej do pojedynczej zamiany, a replaceAll() do wszystkich identycznych wystąpień. Gdy dochodzą warunki, grupy lub ignorowanie wielkości liter, sięgam po wyrażenie regularne i sprawdzam kilka przypadków brzegowych, zanim uznam kod za gotowy.
Najlepszy nawyk przy pracy z zamianą tekstu
Najwięcej problemów nie wynika z samej składni, tylko z niejasnego określenia, co dokładnie ma zostać zmienione. Najpierw ustal zakres dopasowania, potem wybierz najprostsze narzędzie, a na końcu przetestuj pusty tekst, brak dopasowania, wielokrotne wystąpienia i różne warianty wielkości liter.
Taki sposób pracy sprawia, że metoda pozostaje przewidywalna zarówno w małym ćwiczeniu, jak i w kodzie aplikacji. Zamiast zapamiętywać pojedynczy trik, budujesz poprawny model działania: tekst pozostaje niezmienny, metoda zwraca nową wartość, a zakres podmiany zależy od użytego wzorca.