Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
113: Common Regex Recipes for Validation
Think of regex validation like a bouncer at a high-end club. The bouncer doesn't just look at you and guess if you're allowed in; they have a very specific checklist. "Are you wearing a collared shirt? Is your ID valid? Are you on the guest list?" If you fail even one of those specific criteria, you aren't getting through the door. The bouncer isn't interested in who you are as a person—they only care if you match the pattern required for entry.
In Python, re.fullmatch() is your bouncer. Unlike re.search(), which just looks for a pattern anywhere in the string, fullmatch ensures the entire input string conforms to your rules from start to finish. If there's one extra character at the end that doesn't fit, the whole thing is rejected. This is exactly what you want when you're validating user input.
The Bread and Butter: Emails and Passwords
I'll be the first to tell you: writing a "perfect" email regex is a rabbit hole that can swallow your entire afternoon. The actual RFC specification for emails is surprisingly complex. However, for 99% of the apps you'll build, you just need to make sure it looks like an email. Here is a recipe I use most of the time:
import re
def is_valid_email(email):
# This checks for: characters + @ + characters + . + characters
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
return bool(re.fullmatch(pattern, email))
print(is_valid_email("dev_mentor@example.com")) # True
print(is_valid_email("bad-email@com")) # False
Now, passwords are a different beast. You usually aren't looking for one simple pattern, but rather a set of requirements: "At least one uppercase, one lowercase, one digit, and at least 8 characters." To do this in one regex, we use positive lookaheads (?=...). This tells the regex engine: "Look ahead to see if this exists, then jump back to the start and keep checking the rest of the pattern."
def is_strong_password(password):
# Lookahead for digit, lookahead for upper, lookahead for lower, then length check
pattern = r'^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,}$'
return bool(re.fullmatch(pattern, password))
print(is_strong_password("Password123")) # True
print(is_strong_password("pass123")) # False (No uppercase)
Taming Phone Numbers and Dates
Phone numbers are a nightmare because everyone formats them differently. Some use dashes, some use parentheses, some start with +1. The trick here is to make the delimiters optional using the ? quantifier.
def is_valid_phone(phone):
# Optional +, optional 1, optional parens, optional separators
pattern = r'^\+?1?\s*\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$'
return bool(re.fullmatch(pattern, phone))
# These all pass the bouncer
print(is_valid_phone("(555) 123-4567"))
print(is_valid_phone("5551234567"))
print(is_valid_phone("+1 555.123.4567"))
For dates, I usually suggest using the datetime module for actual validation, but if you need to quickly check if a string follows the YYYY-MM-DD format before processing it, a simple digit-count regex is your best bet:
def is_iso_date(date_str):
pattern = r'^\d{4}-\d{2}-\d{2}$'
return bool(re.fullmatch(pattern, date_str))
A Word of Warning on Over-Engineering
I've seen developers spend days crafting a 200-character regex to validate a credit card number, only to realize that the credit card provider has a dedicated library that does it better and handles the checksum logic. Regex is great for format validation, but it's terrible for logic validation. It can tell you if a date looks like 2023-02-31, but it can't easily tell you that February 31st doesn't exist. Use regex to filter the noise, but use Python logic to verify the truth.
📋 Practical Task
Building a User Registration Input Validator
You are building a sign-up form for a new platform. You need to write a validation function validate_user_data(username, zip_code) that checks if the provided inputs meet the following strict requirements:
- Username: Must be 3 to 15 characters long and contain only alphanumeric characters (letters and numbers). No spaces or special characters allowed.
- Zip Code: Must be exactly 5 digits (standard US zip code).
The function should return True only if both inputs are valid, and False otherwise.
import re
def validate_user_data(username, zip_code):
# Your code here
pass
# Test cases to verify your work:
print(validate_user_data("Coder123", "90210")) # Expected: True
print(validate_user_data("Co", "90210")) # Expected: False (Username too short)
print(validate_user_data("Coder_123", "90210")) # Expected: False (Invalid character '_')
print(validate_user_data("Coder123", "9021")) # Expected: False (Zip code too short)
print(validate_user_data("Coder123", "ABCDE")) # Expected: False (Zip code not digits)
There are no comments for now.