Tutorials Logic, IN info@tutorialslogic.com

Regular Expressions in Python re Module

Python Regex

A regular expression is a text pattern. In Python, the re module uses that pattern to search, extract, replace, split, or validate strings.

Use regex when the text has a recognizable shape, such as dates, prices, emails, codes, repeated separators, or structured log lines.

The safest regex habit is to test both matching and non-matching input, because a pattern that works on one example can still match too much or too little.

Regular Expressions

A regular expression (regex) is a pattern used to match, search, and manipulate text. Python's re module provides full regex support.

re Module Functions

Function Description
re.match(pattern, string) Match at the beginning of string
re.search(pattern, string) Search anywhere in string
re.findall(pattern, string) Return all matches as a list
re.finditer(pattern, string) Return iterator of match objects
re.sub(pattern, repl, string) Replace matches with repl
re.split(pattern, string) Split string by pattern
re.compile(pattern) Compile pattern for reuse

Basic Functions

Basic Functions
import re

text = "The price is $25.99 and $10.50"

# search - find first match anywhere
match = re.search(r"\d+\.\d+", text)
if match:
    print(match.group())   # 25.99
    print(match.start())   # 14 (start index)
    print(match.end())     # 19 (end index)

# findall - find all matches
prices = re.findall(r"\$\d+\.\d+", text)
print(prices)   # ['$25.99', '$10.50']

# sub - replace matches
clean = re.sub(r"\$\d+\.\d+", "[PRICE]", text)
print(clean)    # The price is [PRICE] and [PRICE]

# split - split by pattern
sentence = "one,two;three four"
parts = re.split(r"[,; ]+", sentence)
print(parts)    # ['one', 'two', 'three', 'four']

Regex Pattern Syntax

Pattern Matches Example
. Any character (except newline) a.c -> "abc", "a1c"
^ Start of string ^Hello
$ End of string world$
* 0 or more ab* -> "a", "ab", "abb"
+ 1 or more ab+ -> "ab", "abb"
- 0 or 1 (optional) colou-r -> "color", "colour"
{n} Exactly n times \d{4} -> "2024"
{n,m} Between n and m times \d{2,4}
[abc] Any of a, b, c [aeiou]
[^abc] Not a, b, or c [^0-9]
\d Digit [0-9] \d+ -> "123"
\D Non-digit
\w Word char [a-zA-Z0-9_] \w+
\W Non-word char
\s Whitespace \s+
\S Non-whitespace
\b Word boundary \bword\b
(abc) Capture group (\d+)-(\d+)
a|b a or b cat|dog

Capturing Groups

Groups

Groups
import re

# Capture groups with ()
date_str = "Today is 2024-06-15"
match = re.search(r"(\d{4})-(\d{2})-(\d{2})", date_str)
if match:
    print(match.group(0))  # 2024-06-15 (full match)
    print(match.group(1))  # 2024 (year)
    print(match.group(2))  # 06   (month)
    print(match.group(3))  # 15   (day)

# Named groups
match = re.search(r"(-P<year>\d{4})-(-P<month>\d{2})-(-P<day>\d{2})", date_str)
if match:
    print(match.group("year"))   # 2024
    print(match.group("month"))  # 06
    print(match.groupdict())     # {'year': '2024', 'month': '06', 'day': '15'}

# findall with groups returns list of tuples
text = "John: 25, Alice: 30, Bob: 22"
results = re.findall(r"(\w+): (\d+)", text)
print(results)  # [('John', '25'), ('Alice', '30'), ('Bob', '22')]

Regex Examples

Real-World Patterns

Real-World Patterns
import re

# Email validation
def is_valid_email(email: str) -> bool:
    pattern = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
    return bool(re.match(pattern, email))

print(is_valid_email("user@example.com"))   # True
print(is_valid_email("invalid-email"))      # False

# Phone number extraction
text = "Call us at 555-123-4567 or (800) 555-0199"
phones = re.findall(r"[\d\-\(\) ]{10,}", text)
print(phones)

# URL extraction
html = '<a href="https://example.com">Link</a> and <a href="http://test.org">Test</a>'
urls = re.findall(r'https-://[^\s"]+', html)
print(urls)   # ['https://example.com', 'http://test.org']

# Password strength check
def check_password(pwd: str) -> dict:
    return {
        "length": len(pwd) >= 8,
        "uppercase": bool(re.search(r"[A-Z]", pwd)),
        "lowercase": bool(re.search(r"[a-z]", pwd)),
        "digit": bool(re.search(r"\d", pwd)),
        "special": bool(re.search(r"[!@#$%^&*]", pwd)),
    }

result = check_password("MyPass123!")
print(result)

# Compile for reuse (faster when used many times)
email_re = re.compile(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
emails = ["a@b.com", "bad", "x@y.org"]
valid = [e for e in emails if email_re.match(e)]
print(valid)  # ['a@b.com', 'x@y.org']

Test a Regex

A regex should be treated like a small parser. Write the pattern, test the smallest matching string, then test strings that must not match.

Watch greedy operators such as .* and .+. They can swallow more text than expected. Prefer specific character classes, anchors, and bounded repeats when the input shape is known.

If a pattern becomes hard to read, split the task: clean the text first, use named groups, or replace part of the regex with ordinary Python string methods.

  • Test one string that should match.
  • Test one string that should fail.
  • Print match.group() and match.span() when debugging search results.
  • Use re.compile() when the same pattern is used many times.
Regex readiness check

Can Your Regex Match Only the Right Text?

5 checks
  • Use raw strings such as r"\d+" for regex patterns.
  • Choose search(), match(), findall(), or sub() based on the task.
  • Keep complex patterns named and tested with example inputs.
  • Escape characters that should be matched literally.
  • Prefer normal string methods when regex would make the code harder to read.

Regex Decisions

0 of 2 checked

Q1. When should you avoid regex?

Q2. Why are raw strings common for regex patterns?

Regex Matches That Go Too Far

  • Using regex for simple string checks

    Use startswith, endswith, in, split, or replace when they solve the problem clearly.
  • Writing patterns that match too much

    Use anchors, specific character classes, and bounded repeats when the input shape is known.
  • Forgetting raw strings

    Write patterns as r\"...\" so backslashes are read by regex, not Python string escaping first.

Try this next

Match the Right Text

0 of 3 completed

  1. Extract all numbers from a sentence using re.findall.
  2. Match an ID shaped like TL-2026 with anchors.
  3. Collapse repeated spaces in a sentence into one space.

Python Regex Decisions

Use fullmatch when the entire string must follow the pattern. search is for finding a matching part anywhere in the text.

Raw strings stop Python from consuming backslashes before the regular-expression engine sees them.

Yes. Nested or ambiguous repetition can cause extreme backtracking. Keep patterns bounded and test them with long failing input.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.