string manipulation
character replacement
text processing
coding
programming tips

Best way to replace multiple characters in a string?

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

The best approach to replacing multiple characters in a string depends on your language and use case. In Python, str.translate() with str.maketrans() is the fastest for character-level replacements. In JavaScript, use a regex character class with replace(). For multi-character substring replacements, chain .replace() calls or use a dictionary-based approach. Avoid repeated string concatenation in loops — it creates unnecessary intermediate strings.

Python

str.translate() — Fastest for Character Replacement

python
1# Replace multiple characters at once
2text = "Hello, World! How's it going?"
3
4# Create translation table: replace , ! ' with nothing (delete them)
5table = str.maketrans("", "", ",!'")
6result = text.translate(table)
7print(result)  # "Hello World Hows it going?"
8
9# Replace characters with other characters
10table = str.maketrans("aeiou", "12345")
11result = "hello world".translate(table)
12print(result)  # "h2ll4 w4rld"
13
14# Combine replacement and deletion
15table = str.maketrans({"a": "@", "e": "3", "!": None})  # None = delete
16result = "apple pie!".translate(table)
17print(result)  # "@ppl3 pi3"

str.translate() is implemented in C and processes the entire string in one pass — significantly faster than chaining .replace().

Chained .replace()

python
1text = "Hello, World! (2025)"
2
3result = text.replace(",", "").replace("!", "").replace("(", "").replace(")", "")
4print(result)  # "Hello World 2025"

Simple and readable for a few replacements, but each .replace() creates a new string and scans the entire text. For many replacements, use translate() instead.

Regular Expressions

python
1import re
2
3text = "Hello, World! How's it going?"
4
5# Replace any of these characters with nothing
6result = re.sub(r"[,!']", "", text)
7print(result)  # "Hello World Hows it going?"
8
9# Replace with specific substitutions using a function
10def replacer(match):
11    return {"a": "@", "e": "3", "o": "0"}.get(match.group(), match.group())
12
13result = re.sub(r"[aeo]", replacer, "hello world")
14print(result)  # "h3ll0 w0rld"

Dictionary-Based Replacement

python
1text = "The quick brown fox"
2replacements = {"quick": "slow", "brown": "white", "fox": "rabbit"}
3
4# Using reduce
5from functools import reduce
6result = reduce(lambda s, kv: s.replace(*kv), replacements.items(), text)
7print(result)  # "The slow white rabbit"
8
9# Using regex with dict lookup
10import re
11pattern = re.compile("|".join(re.escape(k) for k in replacements))
12result = pattern.sub(lambda m: replacements[m.group()], text)
13print(result)  # "The slow white rabbit"

The regex approach processes the string in a single pass, making it faster for many replacements.

JavaScript

javascript
1// Regex character class — replace multiple chars at once
2const text = "Hello, World! (2025)";
3const result = text.replace(/[,!()]/g, "");
4console.log(result);  // "Hello World 2025"
5
6// Replace with specific values using a map
7const map = { a: "@", e: "3", o: "0" };
8const result2 = "hello world".replace(/[aeo]/g, ch => map[ch]);
9console.log(result2);  // "h3ll0 w0rld"
10
11// replaceAll for substring replacement (ES2021)
12const cleaned = "foo-bar-baz"
13    .replaceAll("-", "_")
14    .replaceAll("foo", "qux");
15console.log(cleaned);  // "qux_bar_baz"

C#

csharp
1// Multiple Replace calls
2string text = "Hello, World! (2025)";
3string result = text
4    .Replace(",", "")
5    .Replace("!", "")
6    .Replace("(", "")
7    .Replace(")", "");
8// "Hello World 2025"
9
10// Regex for character class
11using System.Text.RegularExpressions;
12string result2 = Regex.Replace(text, @"[,!()]", "");
13
14// StringBuilder for many replacements (more efficient)
15var sb = new StringBuilder(text);
16sb.Replace(",", "").Replace("!", "").Replace("(", "").Replace(")", "");
17string result3 = sb.ToString();

Java

java
1// Regex character class
2String text = "Hello, World! (2025)";
3String result = text.replaceAll("[,!()]", "");
4// "Hello World 2025"
5
6// Multiple replacements with a map
7Map<String, String> replacements = Map.of(
8    "quick", "slow",
9    "brown", "white"
10);
11String sentence = "The quick brown fox";
12for (var entry : replacements.entrySet()) {
13    sentence = sentence.replace(entry.getKey(), entry.getValue());
14}
15// "The slow white fox"

Go

go
1package main
2
3import (
4    "fmt"
5    "strings"
6)
7
8func main() {
9    // strings.NewReplacer for multiple pairs
10    r := strings.NewReplacer(
11        ",", "",
12        "!", "",
13        "(", "",
14        ")", "",
15    )
16    result := r.Replace("Hello, World! (2025)")
17    fmt.Println(result)  // "Hello World 2025"
18
19    // Reuse the replacer for multiple strings (efficient)
20    result2 := r.Replace("Another, string!")
21}

Go's strings.NewReplacer is optimized internally — it builds a lookup structure and processes the string in one pass.

Performance Comparison (Python)

python
1import timeit
2
3text = "a" * 10000 + "b" * 10000 + "c" * 10000
4
5# Method 1: chained replace — 3 passes
6timeit.timeit(lambda: text.replace("a", "x").replace("b", "y").replace("c", "z"), number=1000)
7# ~15ms
8
9# Method 2: translate — 1 pass
10table = str.maketrans("abc", "xyz")
11timeit.timeit(lambda: text.translate(table), number=1000)
12# ~3ms
13
14# Method 3: regex — 1 pass with overhead
15import re
16pattern = re.compile("[abc]")
17mapping = {"a": "x", "b": "y", "c": "z"}
18timeit.timeit(lambda: pattern.sub(lambda m: mapping[m.group()], text), number=1000)
19# ~50ms

str.translate() is 5x faster than chained .replace() and 15x faster than regex for character-level replacements.

Common Pitfalls

  • Chaining too many .replace() calls: Each creates a new string and scans the full text. For more than 3-4 replacements, use translate() (Python), NewReplacer (Go), or regex.
  • Overlapping replacements: "abc".replace("a", "b").replace("b", "c") produces "ccc", not "bca". The second replace acts on the output of the first. Use a single-pass approach (regex with dict or translate) to avoid this.
  • Regex special characters: Characters like ., *, (, ) have special meaning in regex. Escape them with re.escape() (Python) or \\ when using them in patterns.
  • Immutable strings: In Python, Java, C#, Go, and JavaScript, strings are immutable. Each .replace() creates a new string. Use StringBuilder (C#/Java) for many mutations in a loop.
  • Case sensitivity: .replace() is case-sensitive by default. Use re.sub(pattern, replacement, text, flags=re.IGNORECASE) for case-insensitive replacement.

Summary

  • Python: str.translate() for character replacement, regex for complex patterns
  • JavaScript: str.replace(/[chars]/g, "") with a regex character class
  • C#/Java: chained .Replace() for few replacements, Regex.Replace() for many
  • Go: strings.NewReplacer() for efficient multi-pair replacement
  • Use single-pass methods (translate, regex, NewReplacer) for best performance
  • Avoid chained .replace() for overlapping replacements — they interact unexpectedly

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.