String.prototype.replace()
replace(pattern, replacement) The replace() method returns a new string with some or all matches of a pattern replaced. Unlike replaceAll(), this method only replaces the first match by default when using a string pattern.
Syntax
str.replace(pattern, replacement)
str.replace(regexp, replacement)
pattern: A string or RegExp to search forreplacement: A string or function to replace the matched text- Returns: A new string with replacements made
Parameters
| Parameter | Type | Description |
|---|---|---|
pattern | string | RegExp | The pattern to search for. If a string, only the first occurrence is replaced. |
replacement | string | function | The replacement string or a function that returns the replacement |
Return Value
A new string with the specified replacements. The original string remains unchanged.
Examples
Basic string replacement
const str = "Hello World";
console.log(str.replace("World", "Universe")); // "Hello Universe"
console.log(str.replace("Hello", "Hi")); // "Hi World"
The basic form swaps one substring for another. When you use a plain string as the pattern, only the first occurrence changes — this is one of the most common surprises with replace. The block below shows what happens when the same word appears multiple times in the input.
Note: Only the first occurrence is replaced when using a string pattern:
const str = "foo foo foo";
console.log(str.replace("foo", "bar")); // "bar foo foo"
To replace every occurrence with a plain string, use replaceAll() or pass a regex with the global flag. The regex approach also enables case-insensitive matching, which is essential when the input casing is unpredictable and you need to match regardless of it.
Using regular expressions
const str = "Hello World";
// Replace all matches with global flag
console.log(str.replace(/o/g, "0")); // "Hell0 W0rld"
// Case-insensitive replacement
console.log(str.replace(/hello/i, "Hi")); // "Hi World"
Once you have a regex match, you can reach into parts of it with capture groups. This is where replace becomes much more than a simple find-and-swap — groups let you reorder, restructure, or selectively preserve parts of the matched text.
Capture Groups
const name = "John Doe";
// $1 and $2 refer to captured groups
console.log(name.replace(/(\w+) (\w+)/, "$2, $1")); // "Doe, John"
// Using named capture groups
console.log(name.replace(/(?<first>\w+) (?<last>\w+)/, "$<last>, $<first>")); // "Doe, John"
Named and numbered groups work well for static reshuffling. When the replacement logic depends on the matched value — for example, doubling a number or redacting data — a function callback gives you full control over what the new string looks like.
Replacement Function
When the replacement is a function, it receives the matched string and can compute a dynamic replacement:
const numbers = "1 2 3 4 5";
// Double each number
const doubled = numbers.replace(/\d+/g, (match) => {
return String(Number(match) * 2);
});
console.log(doubled); // "2 4 6 8 10"
The function receives these arguments:
match: The full matched stringp1, p2, ...: Capture group matchesoffset: Position of the match in the original stringstring: The entire original string
Replacement special characters
In replacement strings, these special characters work:
| Sequence | Description |
|---|---|
$$ | Literal dollar sign |
$& | The matched substring |
| $` | The string before the match |
$' | The string after the match |
$n | The nth capture group |
$<name> | Named capture group |
The special sequences let you reference the match, its position, or captured groups directly inside the replacement string. They save you from writing a callback for simple cases like wrapping or prefixing the matched text.
const text = "abc123def";
// Insert text before and after match
console.log(text.replace(/\d+/, "[$&]")); // "abc[123]def"
// Use matched text in replacement
console.log(text.replace(/(\d+)/, "num: $1")); // "abcnum: 123def"
The special sequences are handy for quick transformations, but they only work with static replacements. Edge cases like missing matches, empty patterns, and non-string arguments can still trip you up, so it is worth knowing what the method does in each situation before you rely on it in production code.
Edge Cases
// No match found - returns original string
console.log("hello".replace("xyz", "abc")); // "hello"
// Empty pattern inserts at start
console.log("hello".replace("", "-")); // "-hello"
// Undefined replacement searches for "undefined"
console.log("hello".replace("h", undefined)); // "undefinedello"
// Null pattern throws error
try {
"hello".replace(null, "x");
} catch (e) {
console.log(e.message); // Null is not a valid argument
}
replace() vs replaceAll()
Use replace() when you want the first match only, or when you are using a replacement function that decides how one match should change. Use replaceAll() when every occurrence should be updated and you do not need custom control over each match. The difference is small, but it matters a lot in user-facing text cleanup.
If you are using a regular expression with the global flag, replace() can still touch every match. That gives you flexibility, but it also means you should be clear about whether the replacement is meant to be selective or broad. Picking the right method makes the intent of the code much easier to read.
Practical replacement patterns
Replacement functions are especially useful when the output depends on the match itself. Formatting numbers, swapping names, and redacting sensitive text all fit that shape. Because the callback receives the match and its position, you can build output that is smarter than a simple string substitution.
One common pattern is to normalize text before displaying it. For example, you can swap repeated whitespace for a single space, turn marker tokens into readable labels, or wrap matched text in markup. Just keep escaping in mind if the replacement is going into HTML or another structured format.
Performance
For replacing all occurrences, use replaceAll() or a regex with the global flag. Creating a new RegExp each iteration is slower:
// Slower: creates new RegExp each time
const slow = str.replace(/foo/g, "bar");
// Or use replaceAll (ES2021+)
const fast = str.replaceAll("foo", "bar");
See Also
- String.prototype.split() — Split string into array
- String.prototype.slice() — Extract portion of string