Regular Expressions › The re Module

Michael BrenndoerferUpdated March 18, 20253 min read
Language AI HandbookAll chapters
Part 1 of 67Text as Data
Chapter 3Regular Expressions › The re Module
Reading section 3 of 21 · The re Module · 3 minSection 3 of 21 · 3 min

Book contents

Section 3 of 21 · 3 min read

Regular Expressions › The re ModuleOne section · Sections in this chapter3 / 21 ↓
Reading tools Definitions & inline links

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Python's re module provides the interface for working with regular expressions. The module ships with Python's standard library, so no installation is needed. It exposes a small set of functions that cover the vast majority of text matching and manipulation tasks. Before diving into pattern syntax, let's understand the main functions you'll use:

In[7]:
Code
import re

text = "Contact us at support@example.com or sales@example.com"

# re.search() - Find first match
first_match = re.search(r"\w+@\w+\.\w+", text)

# re.findall() - Find all matches, return list of strings
all_matches = re.findall(r"\w+@\w+\.\w+", text)

# re.finditer() - Find all matches, return iterator of match objects
match_objects = list(re.finditer(r"\w+@\w+\.\w+", text))

# re.sub() - Replace matches
replaced = re.sub(r"\w+@\w+\.\w+", "[EMAIL]", text)

# re.split() - Split by pattern
parts = re.split(r"\s+", "Hello   world  foo")
Out[8]:
Console
re.search() - First match:
  Match: 'support@example.com' at position (14, 33)

re.findall() - All matches as strings:
  ['support@example.com', 'sales@example.com']

re.finditer() - Match objects with metadata:
  'support@example.com' at (14, 33)
  'sales@example.com' at (37, 54)

re.sub() - Replace matches:
  'Contact us at [EMAIL] or [EMAIL]'

re.split() - Split by pattern:
  ['Hello', 'world', 'foo']

Each function serves a different purpose. Use search() when you only need the first match, findall() when you want a simple list of matched strings, finditer() when you need position information or groups, sub() for replacements, and split() to break text at pattern boundaries.

In practice, findall() is the workhorse for NLP preprocessing because you usually want every occurrence of an entity. finditer() becomes needed when you need to know where matches appear, for example to build a token span list or to highlight matches in a UI. sub() is inuseful for cleaning: removing URLs, anonymizing emails, or normalizing whitespace all come down to substitution. all these functions share the same pattern syntax. Learning the syntax once, you can apply it through any of these interfaces.

Raw Strings

Notice the r prefix before pattern strings: r'\w+@\w+'. This creates a raw string where backslashes are treated literally. Without it, Python interprets backslashes as escape sequences before the regex engine sees them.

In[9]:
Code
# Without raw string: \n becomes a newline character
regular_string = "line1\nline2"

# With raw string: \n stays as backslash-n
raw_string = r"line1\nline2"

# This matters for regex patterns
pattern_wrong = "\bword\b"  # \b becomes backspace character!
pattern_right = r"\bword\b"  # \b stays as word boundary
Out[10]:
Console
Regular string 'line1\nline2':
  'line1\nline2'
  Length: 11 characters

Raw string r'line1\nline2':
  'line1\\nline2'
  Length: 12 characters

Pattern comparison:
  Without r: '\x08word\x08' (backspace character!)
  With r:    '\\bword\\b' (word boundary)

Always use raw strings for regex patterns. It's a habit that will save you from subtle bugs. The rule is simple: every regex pattern string should start with r. The compiler cost is zero and the defensive benefit is high.