iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Quiz

Six regex questions that come up in code review. Pick the right pattern, the right engine, or the right "do not use regex for this". Try first; the answers explain the why.

Six regex questions with reasoning

EXAMPLE
# ============================================================
# Q1) Email validation
# ============================================================
# QUESTION: Which is the right approach for accepting email addresses?
# (a) regex r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
# (b) permissive regex + verify via emailed token
# (c) strict RFC 5321 regex (3000+ characters)
#
# ANSWER: (b). RFC 5321 is ridiculously permissive; a strict regex rejects
# valid addresses. A permissive shape (r'^[^\s@]+@[^\s@]+\.[^\s@]+$') catches
# typos; sending a verification email is the only true validator.

# ============================================================
# Q2) Strip HTML from a string
# ============================================================
# QUESTION: regex or library?
#
# ANSWER: library. (BeautifulSoup, lxml, DOMPurify.)
# HTML is not regular; nested tags, comments, CDATA sections, and entities
# break every 'simple' regex you can imagine. Even '<.*?>' fails on
# <script>foo > 1</script> and the like.

# ============================================================
# Q3) Parse a CSV with quoted fields containing commas
# ============================================================
# QUESTION: regex or library?
#
# ANSWER: library. (csv.reader / Papa Parse.)
# Quoted commas, escaped quotes, multi-line fields, BOMs — each is a separate
# state machine. Use the library; benchmark; never regret it.

# ============================================================
# Q4) ReDoS pattern
# ============================================================
# QUESTION: which of these is at risk of catastrophic backtracking?
# (a) r'^(a+)+$'
# (b) r'^a+$'
# (c) r'^\w+$'
#
# ANSWER: (a). Nested quantifiers + a sentinel that fails the match (e.g. 'aaaa...!')
# create exponential backtracking. Rewrite as (b).
# Mitigations: atomic groups (?>...), RE2 (Go), timeouts on engines that support
# them (.NET, Java with Pattern.MULTILINE).

# ============================================================
# Q5) Multiline log parsing
# ============================================================
# QUESTION: pattern for the Apache combined log format?
#
# ANSWER: use named groups + verbose mode.
import re
LOG_RE = re.compile(r'''
    ^
    (?P<ip>\d{1,3}(?:\.\d{1,3}){3})\s+
    \S+\s+\S+\s+
    \[(?P<ts>[^\]]+)\]\s+
    \"(?P<method>[A-Z]+)\s+(?P<path>[^ ]+)\s+HTTP/[\d.]+\"\s+
    (?P<status>\d{3})\s+(?P<bytes>\d+|-)
''', re.VERBOSE)

# Compile ONCE at module scope, then re.finditer over the stream.

# ============================================================
# Q6) Lookbehind portability
# ============================================================
# QUESTION: r'(?<=\bhttps?://)\S+' to match URL paths after the scheme.
# Works in PCRE, Python, .NET — but does it work in Go?
#
# ANSWER: No. RE2 (Go) does not support lookbehinds.
# Workarounds:
# - Restructure the regex to capture the scheme + path together and slice
# - Use a state-machine parser
# - Use Go's regexp/syntax to detect unsupported constructs at startup

# ============================================================
# Bonus — when is regex objectively the wrong tool?
# ============================================================
# - HTML / XML / JSON / YAML / TOML parsing
# - CSV with quoting
# - 'Almost a regex but with one nested rule' (becomes a parser)
# - Validating credentials, signatures, or anything cryptographically meaningful

# ============================================================
# Scoring
# ============================================================
# 6 / 6 -> can lead a regex review
# 4 / 6 -> bookmark regex/cheatsheet
# < 4   -> read 'Mastering Regular Expressions' (Friedl), the only book on the topic worth reading

Why it matters

Always compile patterns once at module scope and use them many times. The engines internal cache reduces the cost a bit, but explicit compilation removes the per-call lookup entirely — and module-level pattern names make the "what does this regex do?" question reviewable at the import site.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// 3 questions per lesson.
Try it Yourself »

Discussion

Loading…