Replacing part of a string
To swap one piece of text for another, TypeScript strings offer two methods:
s.replace(old, new) // replaces the first occurrence
s.replaceAll(old, new) // replaces every occurrence
Both return a new string. Strings can't be changed after they are created, so the original stays exactly as it was:
let sentence: string = "I love cats";
let result: string = sentence.replace("cats", "dogs");
console.log(result); // I love dogs
console.log(sentence); // I love cats
If you call sentence.replace("cats", "dogs") and throw the result away, nothing visible happens. You have to keep the returned string, either in a new variable or by assigning it back to the old one.
First match versus every match
With a plain string as the first argument, replace changes only the first match. replaceAll changes all of them:
let text: string = "aaa";
console.log(text.replace("a", "b")); // baa
console.log(text.replaceAll("a", "b")); // bbb
If the text doesn't contain the old part at all, you simply get the same text back:
console.log("I love cats".replace("birds", "dogs")); // I love cats
The exercise
The starting code has one variable:
let sentence: string = "I love cats";
The task is to create a string variable named result that holds sentence with "cats" replaced by "dogs".
- Declare
resultbelowsentencewith the typestring. - Call
replaceonsentence. The first argument is the text to find,"cats", and the second is the new text,"dogs". - Assign the returned string to
result.
The finished code:
let sentence: string = "I love cats";
let result: string = sentence.replace("cats", "dogs");
Since "cats" appears only once, replace is enough here, and result holds I love dogs while sentence keeps its old value.
Gotchas
- Forgetting that only the first match changes. If the word appears twice,
replacewith a string leaves the second one alone. UsereplaceAllwhen you want every occurrence replaced. - Discarding the result. A line such as
sentence.replace("cats", "dogs");on its own does nothing useful. Assign it:sentence = sentence.replace("cats", "dogs");(which needslet, notconst). - Matching is case-sensitive.
"I love Cats".replace("cats", "dogs")returns the string unchanged. - Regular expressions behave differently.
replacealso accepts a regular expression, and then thegflag makes it replace every match. A plain string is matched literally, but in a pattern the dot means "any character":
console.log("a.b.c".replace(".", "-")); // a-b.c
console.log("a.b.c".replace(/./g, "-")); // -----
console.log("a.b.c".replaceAll(".", "-")); // a-b-c
replaceAllwith a pattern needs thegflag."aaa".replaceAll(/a/, "b")throws aTypeErrorbecause the regular expression isn't global.
Chaining and special characters
Because every call returns a string, calls can be chained. Each step works on the result of the one before it:
const slug: string = "My Blog Post".toLowerCase().replaceAll(" ", "-");
console.log(slug); // my-blog-post
Chaining replace with a plain string is a common way to get surprising results, because each call still changes only the first match: "hello".replace("l", "L").replace("l", "L") gives heLLo only because it was called twice.
Also be careful with the second argument. In the replacement text, a few character combinations are special. A $ followed by another $ or by & doesn't mean a literal dollar sign and an ampersand:
console.log("a".replace("a", "$$")); // $
console.log("a-b".replace("-", "$&$&")); // a--b
Here $$ becomes a single $, and $& stands for the text that was matched. When you need a replacement that is applied exactly as written, pass a function instead, as in s.replace("a", () => "$$"). For everyday words, none of this comes up.
Replace versus other tools
replace works on text you can name exactly. To cut text out, replace it with an empty string: "a-b-c".replaceAll("-", "") returns abc. To change only a part whose position you know, slice and concatenation may be clearer. And to find out whether a change is needed at all, includes answers that without building a new string. When you have a choice between replace with the g flag and replaceAll with a plain string, the second one is easier to read and doesn't treat characters like the dot as special.
Key takeaways
replace(old, new)changes the first match;replaceAll(old, new)changes every match.- Both return a new string and leave the original unchanged, so keep the result.
- If nothing matches, you get the same text back.
- Matching is case-sensitive, and plain strings are matched literally.