string manipulation
character replacement
text processing
coding
programming tips

Best way to replace multiple characters in a string?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

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

Course illustration
Course illustration

All Rights Reserved.