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
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()
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
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
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
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#
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
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
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.
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