String.prototype.replace()
Returns a new string with the first match of a pattern swapped for a replacement.
replace(pattern, replacement)- Added in JavaScript ES1
Parameters
| Parameter | Type | Description |
|---|---|---|
$pattern | string | RegExp | { [Symbol.replace](): any } | A string or an object with a Symbol.replace method — typically a regular expression. Any value without a Symbol.replace method is coerced to a string and matched literally. |
$replacement | string | ((match: string, ...args: any[]) => string) | A string, in which $-patterns such as $&, $1 and $<name> are expanded, or a function invoked for every match whose return value becomes the replacement text. |
Return value
stringA new string, with one, some, or all matches of the pattern replaced by the specified replacement.
Changelog
- PHP ES2018Named capture groups became available in replacement strings as $<name> and as a groups object passed to a replacer function.
replace() substitutes a pattern in a string and hands back a new string; the original is never modified.
Only the first match, unless the regex is global
With a string pattern, or a regex without the g flag, exactly one occurrence is replaced. To replace every occurrence you either add g to the regex or use replaceAll(), which accepts a plain string and does the loop for you.
Dollar signs in the replacement string
The replacement string is not literal. $& is the whole match, $1…$9 are capture groups, $<name> is a named group, and $` and $' are the text before and after the match. To insert a literal dollar sign you must write $$. This bites hardest when the replacement comes from user data or a currency value.
Function replacements
Passing a function sidesteps all of that escaping. It receives the match, then each capture group, then the offset and the full string (and a groups object when named groups are used). Whatever it returns is inserted verbatim, so it is the right tool for computed replacements — incrementing numbers, looking values up in a map, case conversion.
Example
When to use it
- Reformat a date by reordering its capture groups
- Mask all but the last four digits of a card number
- Convert snake_case keys to camelCase
- Collapse repeated whitespace into single spaces
Frequently asked questions
Why does replace only change the first occurrence?
Because a string pattern, or a regex without the g flag, matches once and stops. Use a global regex like /cat/g, or call replaceAll() with a plain string, to replace every occurrence.
How do I insert a literal $ with String.replace?
Write $$ in the replacement string, since a single $ starts a substitution pattern such as $1 or $&. If the replacement text is dynamic, pass a function instead — its return value is inserted verbatim with no $-expansion.
What arguments does the replacer function receive?
The full match first, then one argument per capture group, then the offset of the match, then the whole input string, and finally a groups object if the regex uses named capture groups. Using rest parameters and .at(-1) is the safest way to reach the groups object.
More examples
Named capture groups in the replacement
The first output is "31.08.2026T14:30" — $<name> pulls each named group into the replacement string. The second shows the function form: when named groups exist, the groups object is the last argument, giving "31/08/26T14:30".
const line = "2026-08-31T14:30";
const re = /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/;
console.log(line.replace(re, "$<d>.$<m>.$<y>"));
console.log(
line.replace(re, (...args) => {
const { y, m, d } = args.at(-1);
return `${d}/${m}/${y.slice(2)}`;
})
);snake_case to camelCase
Each underscore-plus-letter pair is consumed and the letter is uppercased, producing userFirstName, alreadyCamel and noUnderscoresHereOk. A string with no underscores comes back unchanged, which is why the guard-free version is safe.
const toCamel = (s) =>
s.replace(/_([a-z])/g, (_, ch) => ch.toUpperCase());
console.log(toCamel("user_first_name"));
console.log(toCamel("already_camel"));
console.log(toCamel("no_underscores_here_ok"));
console.log(toCamel("plain"));The literal dollar sign trap
The first line mangles the amount because the pattern has a capture group and $1 expands to the text that group matched, giving "Total: PLACE,299". Escaping every $ as $$ fixes it, but the function form is cleaner: its return value is inserted verbatim with no pattern expansion at all. Note that a $n naming a group the pattern does not have is left in place as literal text, so the trap only bites once a capture group exists.
const template = "Total: PLACEHOLDER";
const amount = "$1,299";
// $1 is read as a reference to the capture group
console.log(template.replace(/(PLACE)HOLDER/, amount)); // "Total: PLACE,299"
// Escape it, or better, use a function
console.log(template.replace(/(PLACE)HOLDER/, amount.replaceAll("$", "$$$$"))); // "Total: $1,299"
console.log(template.replace(/(PLACE)HOLDER/, () => amount)); // "Total: $1,299"
Discussion