Knowing a tool's limits is what keeps a clever one-liner from becoming a production bug.
Regular expressions describe regular languages: patterns that need only a fixed amount of memory to recognise. They cannot count arbitrarily deep nesting, so they can't correctly match balanced parentheses, nested HTML tags or JSON objects in general. (Some engines have recursion extensions, but the result is unreadable and fragile.)
Use a real parser instead:
- HTML and XML: an HTML parser (BeautifulSoup, lxml, the DOM).
- JSON, YAML, TOML, CSV: the language's library for that format; CSV in particular has quoting rules a simple split gets wrong.
- URLs:
urllib.parse,new URL(). - Dates and numbers:
datetime.strptimeor a date library will reject2026-02-30, which\d{4}-\d{2}-\d{2}happily accepts.
Some validations are better done loosely. A fully RFC-compliant email regex is enormous and still can't tell whether the address exists; check for something like ^[^@\s]+@[^@\s]+$ and then send a confirmation email.
Regex shines for: searching code and logs, extracting fields from semi-structured lines, quick validation of simple formats (IDs, postcodes, version numbers), and search-and-replace. If a pattern needs comments to explain, or grows beyond a line or two, consider a small hand-written parser or splitting the job into steps with ordinary string methods.
Example
import re, json
from datetime import datetime
from urllib.parse import urlparse
print(bool(re.fullmatch(r"\d{4}-\d{2}-\d{2}", "2026-02-30"))) # True (but not a date!)
try:
datetime.strptime("2026-02-30", "%Y-%m-%d")
except ValueError as e:
print("rejected:", e) # rejected: day is out of range for month
doc = '{"a": {"b": [1, {"c": 2}]}}'
print(json.loads(doc)["a"]["b"][1]["c"]) # 2
u = urlparse("https://ex.com:8080/p/a?q=1#top")
print(u.hostname, u.port, u.query) # ex.com 8080 q=1
print(bool(re.fullmatch(r"[^@\s]+@[^@\s]+", "ana@example.org"))) # True: loose checkRemember
- Regexes can't match arbitrarily nested structures
- Use parsers for HTML, JSON, CSV, URLs and dates
- Validate emails loosely and confirm them another way
Watch out for
- Scraping HTML with regexes that break as soon as attribute order or whitespace changes.