Regular Expressions (re Module)

Module 2 • Session 18 • Comprehensive Guide

re-module metacharacters grouping lookarounds regex-flags

A Regular Expression (Regex) is a powerful sequence of characters defining a search pattern. Python handles regular expressions via the built-in re module. Regex is vital for log processing, input validation, web scraping, search-and-replace pipelines, and data cleaning.

1. Regex Metacharacters & Character Sets Reference

Metacharacters are symbols with special meaning inside regular expression patterns.

A. Standard Metacharacters

Symbol Description Example Pattern Matches
. Matches any single character except newline (unless re.DOTALL used). r"c.t" "cat", "cot", "c9t"
^ Anchors match to the start of the string or line. r"^Admin" "Admin User" (Starts with Admin)
$ Anchors match to the end of the string or line. r"end$" "The end" (Ends with end)
* Matches 0 or more occurrences of preceding character/group. r"go*l" "gl", "gol", "gool", "gooool"
+ Matches 1 or more occurrences of preceding character/group. r"go+l" "gol", "gool" (Not "gl")
? Matches 0 or 1 occurrence (makes character optional or quantifier lazy). r"colou?r" "color", "colour"
{m,n} Matches between m and n occurrences. r"\d{2,4}" "12", "123", "1234"
[] Matches any single character listed inside brackets. r"[aeiou]" Any lowercase vowel
| Alternation operator (OR condition). r"cat|dog" "cat" or "dog"
() Groups expressions together and captures matched sub-strings. r"(\d{3})-(\d{4})" Captures area code and digits separately

B. Special Character Sequences (Escaped Sequences)

Sequence Description Equivalent Character Class
\d Matches any Unicode decimal digit. [0-9]
\D Matches any non-digit character. [^0-9]
\w Matches word character (letters, numbers, underscore). [a-zA-Z0-9_]
\W Matches any non-word character. [^a-zA-Z0-9_]
\s Matches whitespace character (space, tab, newline, return). [ \t\n\r\f\v]
\S Matches any non-whitespace character. [^ \t\n\r\f\v]
\b Word boundary anchor (position between \w and \W). N/A

2. Core `re` Module API Functions

import re # Sample input string log_entry = "2026-08-12 14:32:10 [ERROR] User 'admin_99' failed login from IP 192.168.1.105" # 1. re.search(pattern, string) - Finds first match anywhere in string match_obj = re.search(r"IP\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})", log_entry) if match_obj: print("Found IP Address:", match_obj.group(1)) # 192.168.1.105 print("Match Position Span:", match_obj.span()) # (68, 81) # 2. re.match(pattern, string) - Checks for match starting ONLY at index 0 match_start = re.match(r"\d{4}-\d{2}-\d{2}", log_entry) print("Match at Start:", match_start.group() if match_start else "No Match") # 3. re.findall(pattern, string) - Returns list of all non-overlapping matches digits = re.findall(r"\d+", log_entry) print("All Digit Clusters:", digits) # 4. re.finditer(pattern, string) - Returns iterator yielding Match objects for item in re.finditer(r"'(\w+)'", log_entry): print(f"Quoted string found: {item.group(1)} at index {item.start()}") # 5. re.sub(pattern, replacement, string) - Substitute matched occurrences masked_log = re.sub(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", "[REDACTED_IP]", log_entry) print("Masked Log Entry:", masked_log) # 6. re.split(pattern, string) - Split string by regex pattern matches components = re.split(r"\s+\[|\]\s+", log_entry) print("Split Log Components:", components)

3. Advanced Regex Concepts: Groups, Flags, and Lookarounds

A. Grouping & Named Captures

Parentheses () capture matched sub-expressions into numbered groups (1, 2, 3...). Python also supports named groups using syntax (?P<name>pattern).

# Named Groups Example date_pattern = r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})" text = "Date of event: 2026-08-12" m = re.search(date_pattern, text) if m: print("Year: ", m.group("year")) # 2026 print("Month:", m.group("month")) # 08 print("Dict Output:", m.groupdict()) # {'year': '2026', 'month': '08', 'day': '12'}

B. Regex Compilation Flags

  • re.IGNORECASE / re.I: Case-insensitive matching.
  • re.MULTILINE / re.M: Makes ^ and $ match start/end of each line in multi-line strings.
  • re.DOTALL / re.S: Makes dot . match newline characters \n as well.
  • re.VERBOSE / re.X: Allows whitespaces and inline comments inside regex pattern for readability.
# Verbose Regex with Inline Comments email_regex = re.compile(r""" ^([a-zA-Z0-9_\-\.]+) # Username part @ # Single @ symbol ([a-zA-Z0-9_\-\.]+) # Domain name \.([a-zA-Z]{2,5})$ # Top-Level Domain (TLD) """, re.VERBOSE | re.IGNORECASE) print("Valid Email Check:", bool(email_regex.match("User.Name@Compillo.Com")))

C. Lookahead and Lookbehind Assertions (Lookarounds)

Lookarounds match a pattern based on what precedes or follows it without including that text in the captured match result.

Type Syntax Description Example Pattern & Result
Positive Lookahead (?=pattern) Asserts that following text matches pattern. r"\d+(?=\s*USD)" on "100 USD" ➔ Matches "100"
Negative Lookahead (?!pattern) Asserts that following text does NOT match pattern. r"\d+(?!\s*USD)" on "100 EUR" ➔ Matches "100"
Positive Lookbehind (?<=pattern) Asserts that preceding text matches pattern. r"(?<=\$)\d+" on "$250" ➔ Matches "250"
Negative Lookbehind (?<!pattern) Asserts that preceding text does NOT match pattern. r"(?<!VIP-)\w+" on "User1" ➔ Matches "User1"

🏋️ Try It Yourself: Practice Challenges

Challenge 1: Email Address Extractor & Validator

Write a script using re.findall() and named groups that extracts all valid email addresses from an unformatted block of text, separating username and domain components.

Challenge 2: Log File Anonymizer with Lookbehinds

Using re.sub() combined with lookbehind assertions ((?<=...)), automatically mask all credit card numbers and phone numbers in a server log string while leaving preceding transaction IDs untouched.

Challenge 3: Password Complexity Verification Engine

Design a function using lookaheads ((?=.*[A-Z]), (?=.*\d), (?=.*[@$!%*?&])) that tests whether a candidate password string contains at least 8 characters, one uppercase letter, one digit, and one special character.

Challenge 4: CamelCase to Snake_Case Convertor

Construct a regex replacement pipeline using re.sub() that converts CamelCase identifiers (e.g., "CalculateTotalUserScore") into lowercase snake_case (e.g., "calculate_total_user_score").

Challenge 5: HTML Tag Content Extractor

Write a non-greedy regex search pattern using lazy quantifiers (.*?) that strips out all HTML tags from an HTML snippet while preserving text content between tags.

⚡ Interactive Sandbox (Regular Expressions (re Module) Masterclass in Python)
Console Output:
Click "Run Code" above to execute interactive scripts...

📝 Knowledge Check Quiz

1. Why is prefixing regex pattern strings with `r` (raw string literal) recommended in Python?
2. What is the key difference between `re.match()` and `re.search()`?
3. How do you make a greedy quantifier like `.*` perform non-greedy (lazy) matching?
Advertisement
Horizontal Ad Banner Slot (728x90 / Responsive)