Search & Replace

In programming, especially when working with text data, the ability to search for specific patterns and replace them with something else is invaluable. Whether you're cleaning data, updating text, or manipulating strings dynamically, mastering search and replace techniques in Python will make your code more powerful and flexible.

This lesson explores the essentials of searching and replacing text in Python. We'll explore simple string methods, delve into the power of regular expressions, and highlight best practices to avoid common pitfalls. By the end, you'll be able to harness Python’s tools to confidently find and substitute text in your programs.

Understanding the Basics: Strings & Immutability

Before diving into search & replace techniques, it’s important to remember that Python strings are immutable. This means once a string is created, it cannot be changed. Any method that looks like it modifies a string actually returns a new string.

For example, using the replace() method does not alter the original string but returns a new one with the substitutions applied.

📌 Deep Dive: String Replace Basics

PYTHON
text = "Hello world! Hello everyone!"
new_text = text.replace("Hello", "Hi")

print(text)      # Original string remains unchanged
print(new_text)  # New string with replaced text
Output
Hello world! Hello everyone! Hi world! Hi everyone!

Using str.replace(): The Simple Way

The replace() method on Python strings is the simplest way to search and replace text. It takes two required arguments:

  • old: The substring you want to find.
  • new: The substring you want to replace it with.

Optionally, you can specify a count argument to limit how many occurrences to replace.

For example, replace only the first occurrence:

📌 Deep Dive: Limiting Replacements

PYTHON
text = "apple, apple, apple"
new_text = text.replace("apple", "orange", 2)

print(new_text)
Output
orange, orange, apple

Key points about str.replace():

  • It performs a literal substring match, not pattern matching.
  • It is case-sensitive.
  • It returns a new string, leaving the original unchanged.

Case Sensitivity and Exact Matches

If you want to replace text regardless of case, str.replace() alone won’t suffice. For example, replacing “Hello” won’t replace “hello” or “HELLO”.

To perform case-insensitive replacements, you can use the re module, which supports regular expressions.

Unlocking Power with Regular Expressions (re module)

Python’s built-in re module provides a powerful way to search and replace using patterns. Instead of just looking for exact substrings, you can define flexible patterns, including wildcards, character classes, repetitions, and more.

The main function for search and replace using regular expressions is re.sub(). Its signature is:

re.sub(pattern, repl, string, count=0, flags=0)
  • pattern: The regex pattern to search for.
  • repl: The replacement string or a function called on each match.
  • string: The original string.
  • count: Maximum number of replacements (0 = replace all).
  • flags: Regex flags like re.IGNORECASE.

📌 Deep Dive: Basic Regex Replace

PYTHON
import re

text = "The rain in Spain"
new_text = re.sub(r"ain", "___", text)

print(new_text)
Output
The r___ in Sp___

Case-Insensitive Replacement

To replace text ignoring case, you can pass the re.IGNORECASE flag:

📌 Deep Dive: Case-Insensitive Replace with Regex

PYTHON
import re

text = "Hello hello HELLO"
new_text = re.sub(r"hello", "hi", text, flags=re.IGNORECASE)

print(new_text)
Output
hi hi hi

Dynamic Replacements with Functions

Sometimes your replacement depends on the matched text. For example, you want to replace numbers with their squares, or modify matched text dynamically. With re.sub(), you can provide a function as the replacement argument.

This function receives a match object and returns the replacement string.

📌 Deep Dive: Functional Replacement Example

PYTHON
import re

def square_num(match):
    num = int(match.group())
    return str(num ** 2)

text = "Numbers: 2, 3, and 4."
new_text = re.sub(r"\d+", square_num, text)

print(new_text)
Output
Numbers: 4, 9, and 16.

Comparing str.replace() and re.sub()

To clarify when to use which method, consider the following comparison: