Tools (regex101, etc.)
The fastest way to write correct regex is to never write them blind. The tools — regex101, debuggex, regexr, oniguruma testers, the engines built-in debugger — show you matches in real time, explain captures, and visualise the NFA. A 30-second visit beats a 30-minute production bug.
Visualising, testing, and shipping regex with confidence
EXAMPLE
# 1) Online testers — what they do well
# regex101.com: multi-flavour (PCRE2, JS, Python, Go, Java, .NET); explanation column;
# 'code generator' for your language; saved permalinks for sharing.
# debuggex.com: railroad diagrams that make alternation and groups visible.
# regexr.com: a faster regex101 with a cheat sheet sidebar; great for teaching.
# rextester / playgrounds: when you specifically need to test inside a target language.
# 2) Always set the right FLAVOUR. JS regex != PCRE != Python. Common gotchas:
# - Lookbehinds: variable-length supported in PCRE2 and modern V8, NOT in old JS.
# - Named groups: \\k<name> in PCRE, ${1} in Go, \\g<1> in some flavours.
# - Unicode properties: \\p{L} requires the u flag in JS and -P in grep.
# - Comments: /(?#...)/ in PCRE; extended mode /x lets you spread regex across lines.
# 3) Use the language's own debugger when available
# Python:
import re
m = re.search(r'(?P<ip>\d+\.\d+\.\d+\.\d+) \[(?P<ts>[^\]]+)\]', line)
m.groupdict()
# Inside a debugger (pdb / pytest -s) you can iterate fast.
# .NET:
# var rx = new Regex(@"(?<word>\w+)", RegexOptions.Compiled);
# Console.WriteLine(rx.Match("hello world").Groups["word"].Value);
# Go: package regexp + the official Playground
# https://go.dev/play/ -> paste, hit Run.
# 4) Write 'x' (extended) mode for anything longer than 40 characters
import re
LOG_RE = re.compile(r'''
^
(?P<ip>\d+\.\d+\.\d+\.\d+) # client IP
\s+\S+\s+\S+\s+
\[(?P<ts>[^\]]+)\]\s+ # timestamp
"(?P<method>[A-Z]+)\s+(?P<path>[^ ]+) # HTTP method + path
\s+HTTP/[\d.]+"\s+
(?P<status>\d{3})\s+(?P<bytes>\d+|-) # status + bytes
''', re.VERBOSE)
# 5) CLI tools — regex at the shell
# ripgrep: rg -e 'pat' -t py
# pcre2grep: pcre2grep -M 'multi-line pat' file
# perl one-liner: perl -ne '/(?<w>\w+)/ && print "$+{w}\n"' file
# sed (BRE/ERE): sed -E 's/^foo/bar/'
# awk: awk '/^WARN/{print $0}'
# 6) Linters and analysers
# eslint-plugin-regexp / eslint-plugin-regex (JS)
# safe-regex (JS, detects exponential)
# rxxr2 (research-grade ReDoS analysis)
# JetBrains IDEs: Cmd+R inside a string opens 'Edit regex' with live preview
# 7) When a regex feels hairy, add a TEST
# tests/test_log_re.py
def test_log_re_simple():
line = '1.2.3.4 - - [11/Jun/2026:10:32:14 +1000] "GET /a HTTP/1.1" 200 17'
m = LOG_RE.match(line)
assert m and m['ip'] == '1.2.3.4' and m['status'] == '200'
Why it matters
For anything customer-facing, prefer a dedicated parser to a regex. Email, URL, phone, address — they look regexable until they meet international users. Reach for the language standard libraries when you can, and use regex for what regex is good at: log parsing, text extraction from a known format, and quick CLI manipulation.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// regex101.com — interactive flavour-aware tester. // regexr.com — visual cheatsheet. // Languages that ship RE2 (Go, partly TS) cap pathological patterns automatically.Try it Yourself »
Discussion
Loading…