Skip to content

Python String Replace: Complete Guide to str.replace() and Beyond

Updated on

String replacement is one of the most frequent operations in text processing. You need to clean user input, normalize data formats, redact sensitive information, or transform template strings. Python's str.replace() handles simple cases in one line, but it falls short when you need case-insensitive matching, regex patterns, or conditional replacements. Reaching for the wrong tool means either overcomplicating simple tasks or writing brittle code for complex ones.

This guide covers every approach to string replacement in Python -- from the basic str.replace() to regex-powered re.sub(), character-level translate(), and practical patterns for real-world text processing.

📚

str.replace(old, new, count)

The simplest and most common method. Replaces all occurrences of old with new. An optional count limits the number of replacements.

text = "Hello World, Hello Python, Hello Everyone"
 
# Replace all occurrences
print(text.replace("Hello", "Hi"))
# Hi World, Hi Python, Hi Everyone
 
# Replace only first 2 occurrences
print(text.replace("Hello", "Hi", 2))
# Hi World, Hi Python, Hello Everyone
 
# Remove a substring (replace with empty string)
messy = "  extra   spaces   here  "
print(messy.replace(" ", ""))
# extraspaceshere

Key Behavior

  • Returns a new string (strings are immutable in Python)
  • Case-sensitive by default
  • Replaces all occurrences unless count is specified
  • Returns the original string unchanged if old is not found
original = "Python is great"
new = original.replace("great", "awesome")
print(original)  # Python is great (unchanged)
print(new)       # Python is awesome

Case-Insensitive Replace

str.replace() is always case-sensitive. For case-insensitive replacement, use re.sub() with the re.IGNORECASE flag.

import re
 
text = "Python is Great, python is Fun, PYTHON is Everywhere"
 
# Case-insensitive replace
result = re.sub(r'python', 'Java', text, flags=re.IGNORECASE)
print(result)
# Java is Great, Java is Fun, Java is Everywhere

Regex Replace with re.sub()

re.sub(pattern, replacement, string, count, flags) replaces matches of a regex pattern.

import re
 
# Replace digits with '#'
text = "Call 555-1234 or 555-5678"
print(re.sub(r'\d', '#', text))
# Call ###-#### or ###-####
 
# Replace whole phone numbers
print(re.sub(r'\d{3}-\d{4}', '[REDACTED]', text))
# Call [REDACTED] or [REDACTED]
 
# Replace multiple whitespace with single space
messy = "too    many     spaces   here"
print(re.sub(r'\s+', ' ', messy))
# too many spaces here

Using Capture Groups

import re
 
# Swap first and last name
names = "Smith, John\nDoe, Jane\nBrown, Bob"
swapped = re.sub(r'(\w+), (\w+)', r'\2 \1', names)
print(swapped)
# John Smith
# Jane Doe
# Bob Brown
 
# Add formatting to dates
dates = "Meeting on 2026-02-10 and 2026-03-15"
formatted = re.sub(r'(\d{4})-(\d{2})-(\d{2})', r'\2/\3/\1', dates)
print(formatted)
# Meeting on 02/10/2026 and 03/15/2026

Using a Function for Dynamic Replacement

Pass a function instead of a string for conditional replacements:

import re
 
def censor_word(match):
    word = match.group()
    return word[0] + '*' * (len(word) - 1)
 
text = "The password is secret and the code is hidden"
censored = re.sub(r'secret|hidden', censor_word, text)
print(censored)
# The password is s***** and the code is h*****
import re
 
# Convert to title case only for specific words
def smart_capitalize(match):
    word = match.group()
    minor_words = {'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to'}
    if word.lower() in minor_words:
        return word.lower()
    return word.capitalize()
 
title = "the quick BROWN fox AND the lazy DOG"
result = re.sub(r'\b\w+\b', smart_capitalize, title)
print(result)
# the Quick Brown Fox and the Lazy Dog

Multiple Replacements

Chain replace() Calls

text = "Hello World! How are you?"
result = text.replace("Hello", "Hi").replace("World", "Earth").replace("you", "they")
print(result)  # Hi Earth! How are they?

Dictionary-Based Replace

For many replacements, use a dictionary with re.sub():

import re
 
def multi_replace(text, replacements):
    """Replace multiple substrings using a dictionary."""
    pattern = re.compile('|'.join(re.escape(k) for k in replacements))
    return pattern.sub(lambda m: replacements[m.group()], text)
 
text = "The cat sat on the mat with another cat"
replacements = {
    'cat': 'dog',
    'mat': 'rug',
    'sat': 'stood',
}
 
print(multi_replace(text, replacements))
# The dog stood on the rug with another dog

Character-Level Replace with translate()

For replacing individual characters, str.translate() with str.maketrans() is the fastest option:

# Replace characters: a->@, e->3, o->0
table = str.maketrans('aeo', '@30')
text = "Hello World"
print(text.translate(table))
# H3ll0 W0rld
 
# Remove specific characters
remove_vowels = str.maketrans('', '', 'aeiouAEIOU')
print("Hello World".translate(remove_vowels))
# Hll Wrld
 
# Replace AND remove in one call
table = str.maketrans({'a': '@', 'e': '3', ' ': None})
print("apple pie".translate(table))
# @ppl3pi3

Method Comparison

MethodBest ForRegexSpeedFlexibility
str.replace()Simple, literal replacementsNoFastestLow
re.sub()Pattern matching, complex rulesYesModerateHighest
str.translate()Single character mappingNoVery fastLow
Chained .replace()A few literal replacementsNoFastLow
Dict + re.sub()Many simultaneous replacementsYesModerateHigh

Practical Examples

Clean and Normalize Text

import re
 
def clean_text(text):
    """Normalize text for processing."""
    text = text.strip()
    text = re.sub(r'\s+', ' ', text)           # Collapse whitespace
    text = re.sub(r'[^\w\s.,!?-]', '', text)   # Remove special chars
    text = text.lower()
    return text
 
raw = "  Hello!!!   This is    MESSY @#$ text...  "
print(clean_text(raw))
# hello!!! this is messy text...

Template String Replacement

template = "Dear {name}, your order #{order_id} ships on {date}."
 
data = {
    'name': 'Alice',
    'order_id': '12345',
    'date': 'Feb 15, 2026',
}
 
# Using str.format_map (better than manual replace)
result = template.format_map(data)
print(result)
# Dear Alice, your order #12345 ships on Feb 15, 2026.

Redact Sensitive Data

import re
 
def redact_pii(text):
    """Redact emails, phone numbers, and SSNs."""
    text = re.sub(r'\b[\w.]+@[\w.]+\.\w+\b', '[EMAIL]', text)
    text = re.sub(r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b', '[PHONE]', text)
    text = re.sub(r'\b\d{3}-\d{2}-\d{4}\b', '[SSN]', text)
    return text
 
msg = "Contact john@example.com or call 555-123-4567. SSN: 123-45-6789"
print(redact_pii(msg))
# Contact [EMAIL] or call [PHONE]. SSN: [SSN]

Processing Text Data in Jupyter

Text cleaning and transformation is iterative work -- you test patterns against sample data, adjust regex, and verify results. RunCell (opens in a new tab) is an AI agent for Jupyter that can help you build and debug text processing pipelines interactively, testing replacement patterns against your actual data in real time.

FAQ

How do I replace a substring in Python?

Use str.replace(old, new) for simple replacements: "hello world".replace("world", "python") returns "hello python". This replaces all occurrences. Add a third argument to limit replacements: text.replace("a", "b", 2) replaces only the first 2 matches.

How do I do case-insensitive replacement in Python?

Use re.sub() with the re.IGNORECASE flag: re.sub(r'python', 'Java', text, flags=re.IGNORECASE). The built-in str.replace() method does not support case-insensitive matching.

How do I replace multiple different strings at once?

Build a regex pattern from a dictionary of replacements: create a compiled pattern matching all keys, then use a lambda to look up the replacement for each match. Alternatively, chain .replace() calls for a small number of literal replacements.

What is the difference between str.replace() and re.sub()?

str.replace() does literal string matching only -- it is faster and simpler. re.sub() uses regular expressions, supporting pattern matching, capture groups, backreferences, and function-based replacements. Use str.replace() for simple literal swaps and re.sub() when you need pattern flexibility.

How do I remove characters from a string in Python?

Three approaches: str.replace(char, "") removes all occurrences of a specific substring. str.translate(str.maketrans("", "", chars)) efficiently removes all specified characters. re.sub(r"[pattern]", "", text) removes characters matching a regex pattern.

Conclusion

Python offers multiple tools for string replacement, each suited to different complexity levels. Use str.replace() for simple literal swaps, re.sub() for pattern matching and complex rules, and str.translate() for fast character-level mapping. For multiple simultaneous replacements, a dictionary-driven re.sub() approach keeps your code clean and maintainable.

📚