Regular expressions — regex — describe a pattern of characters so you can search, match, or replace text without writing a parser by hand. They show up in form validation, log parsing, find-and-replace across a codebase, and data cleaning scripts. The syntax is famously terse, which is exactly why regex has a reputation for being write-once, read-never.
What changed in 2026
- AI coding assistants now generate and explain regex patterns on request, which lowered the barrier to using regex correctly but did not remove the need to understand what a pattern actually matches.
- Named capture groups (
(?<name>...)) are now standard practice across JavaScript, Python, and most modern languages, replacing fragile numbered groups in new code.
- Regex-heavy validation is increasingly being replaced by dedicated parsing libraries for anything beyond simple patterns — email and URL validation in particular moved toward schema libraries in many codebases.
How regex actually works
A regex engine reads your pattern and your input string left to right, trying to match the pattern against the string starting at each position. Most engines used in mainstream languages are "backtracking" engines: when a partial match fails, the engine backs up and tries a different path. This is why certain patterns — especially ones with nested repetition — can become catastrophically slow on specific inputs, an issue known as catastrophic backtracking.
Core building blocks
| Symbol |
Meaning |
Example |
. |
Any character except newline |
a.c matches "abc", "axc" |
* / + |
Zero-or-more / one-or-more repetitions |
ab* matches "a", "ab", "abb" |
[...] |
Character class |
[0-9] matches any digit |
() |
Capture group |
(\d{3})-(\d{4}) captures two groups |
| |
Alternation |
cat|dog matches either word |
^ $ |
Start / end anchors |
^Hello$ matches only the exact string "Hello" |
(?=...) |
Lookahead |
foo(?=bar) matches "foo" only if followed by "bar" |
When regex is the right tool — and when it is not
Regex is a good fit for simple, well-bounded patterns: extracting a date format, validating a ZIP code shape, splitting on a delimiter. It is a poor fit for parsing anything with nested structure — HTML, JSON, or programming languages — because those require a real parser with state, not a flat pattern match. The common advice "do not parse HTML with regex" exists because HTML nesting cannot be reliably expressed in a regular language.
Common mistakes
- Writing a pattern that is technically correct but catastrophically slow on pathological input, due to nested quantifiers like
(a+)+.
- Using regex for full email or URL validation. The formal specs are absurdly complex; a simple regex will reject valid addresses and accept invalid ones. A basic sanity-check pattern plus a confirmation step is more reliable.
- Forgetting to escape special characters when building a pattern from user input, which can also be a security issue (regex injection).
- Not testing against edge cases — empty strings, unicode characters, and multi-line input all break naive patterns.
FAQ
Is regex the same across every programming language?
Mostly, but not entirely. The core syntax (., *, [], groups) is shared, but lookbehind support, unicode handling, and flags vary by language and engine. Always test in the actual runtime you are shipping to.
What is catastrophic backtracking?
A pathological case where a regex engine explores an exponential number of paths trying to match certain inputs against certain patterns, causing the match to take seconds or minutes instead of milliseconds. It is a real denial-of-service vector for user-supplied patterns or input.
Should I use regex or a parsing library?
For flat, bounded patterns, regex is fine. For anything with nesting or a real grammar, use a parser. This overlaps with clean code discipline generally — see DRY vs WET code for a related judgment call about when a shortcut becomes a liability.
How do I test a regex pattern safely?
Use an online regex tester with your target engine selected, and always test against edge cases (empty input, very long input, unicode) before shipping.
Where to go next