Replacing & Splitting
Replacing and splitting are the workhorses of string transformation. Whether you are sanitizing user input, parsing CSV rows, or templating output, you will reach for replace, replaceAll, split, and join constantly. Because strings in JavaScript are immutable, every one of these methods returns a new string (or array) rather than mutating the original — a detail that trips up beginners. This page walks through each method with its string, regex, and function-based variants.
Replacing with replace()
String.prototype.replace(pattern, replacement) returns a new string with matches of pattern swapped for replacement. When pattern is a plain string, only the first occurrence is replaced.
const path = "src/utils/utils.js";
console.log(path.replace("utils", "helpers"));
console.log(path); // original is untouched
Output:
src/helpers/utils.js
src/utils/utils.js
To replace every occurrence with replace, you must pass a regular expression with the global (g) flag:
const csv = "a,b,c,d";
console.log(csv.replace(/,/g, " | "));
Output:
a | b | c | d
Special replacement patterns
The replacement string can reference parts of the match using special $ patterns. This is powerful for reordering captured groups without writing a function.
| Pattern | Meaning |
|---|---|
$& | The entire matched substring |
$` | The portion before the match |
$' | The portion after the match |
$n | The nth captured group |
$<name> | A named captured group |
$$ | A literal $ |
const date = "2026-06-01";
// Reorder ISO date to DD/MM/YYYY using named groups
const formatted = date.replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
"$<d>/$<m>/$<y>"
);
console.log(formatted);
Output:
01/06/2026
Function replacers
When the replacement depends on the match itself, pass a function. It receives the matched text, then any capture groups, then the offset and the full string. The return value becomes the replacement.
const prices = "Coffee $3 and Cake $5";
const doubled = prices.replace(/\$(\d+)/g, (match, amount) => {
return "$" + Number(amount) * 2;
});
console.log(doubled);
Output:
Coffee $6 and Cake $10
The function replacer runs once per match, so it is the cleanest way to apply per-match logic (case conversion, math, lookups) without an external loop.
Replacing all matches with replaceAll()
Introduced in ES2021, replaceAll removes the need for a global regex when you simply want to swap every occurrence of a literal string. It is clearer and avoids regex-escaping headaches.
const messy = "yes...no...maybe...yes";
console.log(messy.replaceAll("...", " / "));
Output:
yes / no / maybe / yes
replaceAll accepts the same regex and function replacers as replace, but if you pass a regex it must carry the g flag — otherwise it throws a TypeError.
| Method | Replaces | String pattern | Regex pattern |
|---|---|---|---|
replace | First match (or all with /g) | First only | First, or all if g flag |
replaceAll | All matches | All occurrences | Requires g flag |
Splitting strings with split()
String.prototype.split(separator, limit) breaks a string into an array of substrings. The separator can be a string or a regular expression, and the optional limit caps how many pieces are returned.
const tags = "react,vue,svelte,angular";
console.log(tags.split(","));
console.log("hello".split("")); // into characters
console.log("oneword".split(",")); // no separator found
Output:
[ 'react', 'vue', 'svelte', 'angular' ]
[ 'h', 'e', 'l', 'l', 'o' ]
[ 'oneword' ]
A few behaviors worth memorizing:
- Splitting on
""returns an array of UTF-16 code units, which can break surrogate pairs (emoji). Use the spread operator[...str]orArray.fromfor code-point-safe splitting. split()with no argument returns the whole string as a single-element array.- A regex separator lets you split on patterns and even keep delimiters via capture groups.
const messy = "one two three\tfour";
// Split on any run of whitespace
console.log(messy.split(/\s+/));
// Keep the delimiter using a capture group
console.log("a1b2c".split(/(\d)/));
// limit caps the output length
console.log("a-b-c-d".split("-", 2));
Output:
[ 'one', 'two', 'three', 'four' ]
[ 'a', '1', 'b', '2', 'c' ]
[ 'a', 'b' ]
Beware:
"a,b,c".split(",", 2)returns['a', 'b']and discards the rest —limittruncates, it does not merge the remainder into the last element.
Joining arrays with join()
Array.prototype.join(separator) is the natural inverse of split. It glues array elements into a single string, inserting separator (default ,) between them. null and undefined elements become empty strings.
const parts = ["2026", "06", "01"];
console.log(parts.join("-"));
console.log(["a", "b", "c"].join("")); // concatenate
console.log([1, null, 3, undefined].join("|"));
Output:
2026-06-01
abc
1||3|
A common round-trip pattern is split → transform → join:
const slug = "Hello World Example"
.toLowerCase()
.split(" ")
.join("-");
console.log(slug);
Output:
hello-world-example
Best Practices
- Prefer
replaceAllover a global regex when replacing a literal substring — it reads better and avoids escaping regex metacharacters. - Remember
replacewith a string pattern only swaps the first match; reach for/gorreplaceAllfor all of them. - Use a function replacer instead of a manual loop when the replacement depends on each match.
- For character-by-character work, split with the spread operator
[...str]to stay Unicode-safe instead ofsplit(""). - Never expect these methods to mutate in place — always capture the returned value.
- Pair
splitandjoinfor clean transform pipelines, and pass an explicit separator tojoinsince the default comma is rarely what you want.