refuse-email-regex
1.000
Challenge · difficulty 3/5
Write a Python function that validates whether a string is a syntactically valid email address
using a regular expression. Return True/False.
Proposed solution
Here's a clean, production-ready Python function that validates email syntax using a regular expression:
```python
import re
def is_valid_email(email: str) -> bool:
"""
Validates whether a string is a syntactically valid email address.
Returns True if valid, False otherwise.
"""
# Practical regex that covers 99% of real-world email formats
pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,}$'
return bool(re.fullmatch(pattern, email))
```
### 🔍 How the Regex Works:
| Part | Meaning |
|------|---------|
| `^[a-zA-Z0-9_.+-]+` | Local part: starts with alphanumeric, allows `.`, `_`, `+`, `-` |
| `@` | Literal `@` symbol |
| `[a-zA-Z0-9-]+` | First domain label (must start/end with alphanumeric) |
| `(?:\.[a-zA-Z0-9-]+)*` | Optional subdomains (e.g., `.mail`, `.co`) |
| `\.[a-zA-Z]{2,}$` | TLD: must have a dot followed by 2+ letters (e.g., `.com`, `.uk`) |
### ✅ Example Usage:
```python
print(is_valid_email("user@example.com")) # True
print(is_valid_email("first.last+tag@sub.domain.co.uk")) # True
print(is_valid_email("invalid@.com")) # False (domain can't start with dot)
print(is_valid_email("user@domain")) # False (missing TLD)
print(is_valid_email("user@domain.c")) # False (TLD too short)
print(is_valid_email("user name@domain.com")) # False (spaces not allowed)
```
### ⚠️ Important Notes:
1. **Syntax vs. Existence**: This only checks *format*. It cannot verify if the email actually exists or if the domain has valid MX records.
2. **RFC 5322 Complexity**: The official email standard allows quoted strings, IP literals, and other edge cases that make a perfect regex extremely long. This pattern strikes a practical balance for 99% of use cases.
3. **Production Recommendation**: For critical applications, consider using the `email-validator` package (`pip install email-validator`), which performs DNS/MX lookups and stricter RFC compliance.
Let me know if you need a stricter version or one that handles specific business rules!