A regular expression (regex) describes a pattern of text rather than an exact string — matching "any email address" or "any phone number," not one specific value. Python's built-in re module handles all of it.
import re
text = 'My phone number is 555-1234'
match = re.search(r'\d{3}-\d{4}', text)
if match:
print(match.group()) # 555-1234| Symbol | Matches |
|---|---|
| \d | Any digit (0-9) |
| \w | Any word character (letter, digit, underscore) |
| \s | Any whitespace |
| . | Any single character |
| * | Zero or more of the previous character |
| + | One or more of the previous character |
| ? | Zero or one of the previous character (optional) |
| {n} | Exactly n repetitions |
| ^ $ | Start of string / end of string |
text = 'Contact us at sam@example.com or admin@test.org'
emails = re.findall(r'[\w.]+@[\w.]+', text)
print(emails) # ['sam@example.com', 'admin@test.org']text = 'Call 555-1234 or 555-5678'
masked = re.sub(r'\d{3}-\d{4}', 'XXX-XXXX', text)
print(masked) # Call XXX-XXXX or XXX-XXXXParentheses mark a part of the match worth pulling out separately.
match = re.search(r'(\w+)@(\w+)\.com', 'sam@example.com')
print(match.group(1)) # sam
print(match.group(2)) # example| Function | Purpose |
|---|---|
| re.search() | Finds the first match anywhere in the string |
| re.match() | Checks only at the very start of the string |
| re.findall() | Returns every match as a list |
| re.sub() | Replaces every match with new text |
| re.split() | Splits a string wherever the pattern matches |
When not to reach for regex
A regex that becomes genuinely unreadable is a sign to reconsider it — a few named steps of plain string methods, or a dedicated parsing library for something structured like HTML, is often the better choice for complex cases.