DevKit
← Back to Blog

Regex Cheatsheet: Common Patterns Every Developer Reuses

8 min read

Most developers do not write regular expressions from scratch every day. They reach for the same handful of patterns, tweak them, and move on. The trouble is that half-remembered patterns tend to be subtly wrong, and a wrong pattern that mostly works is worse than no pattern at all.

This cheatsheet collects the patterns people actually reuse, explains the building blocks underneath them, and points out the places where regex quietly bites back.

The building blocks

Character classes

A character class matches one character from a set. The square brackets define the set:

[abc]      one of a, b, or c
[a-z]      any lowercase letter
[0-9]      any digit
[^0-9]     any character that is NOT a digit

Shorthand classes save typing: \d matches a digit, \w matches a word character (letters, digits, underscore), and \s matches whitespace. Their uppercase versions negate: \D, \W, and \S.

Quantifiers

Quantifiers say how many times the preceding token repeats:

*       zero or more
+       one or more
?       zero or one (optional)
{3}     exactly 3
{2,5}   between 2 and 5
{2,}    2 or more

By default quantifiers are greedy, meaning they grab as much as possible. Adding ? makes them lazy, so .*? matches as little as it can. That difference matters a lot when parsing tags or quoted strings.

Anchors

Anchors match a position, not a character. ^ matches the start of the input, $ matches the end, and \b matches a word boundary. Without anchors, a pattern can match in the middle of a longer string, which is a frequent source of validation bugs.

Groups

Parentheses create a capturing group you can reference later. If you only need grouping without capture, use (?:...). Named groups like (?P<year>\d{4}) make extracted values readable.

Patterns you will reuse

Email (practical, not perfect)

^[\w.+-]+@[\w-]+\.[\w.-]+$

Fully RFC-compliant email validation is almost impossible with a single regex, and you gain little by chasing it. A loose pattern plus a confirmation email is the realistic approach. This pattern accepts the vast majority of real addresses and rejects obvious garbage.

URL

^https?://[\w.-]+(?:\.[a-z]{2,})(?:/[^\s]*)?$

This matches an http or https address with a hostname, a top-level domain of at least two letters, and an optional path. For anything beyond basic validation, use your language URL parser instead.

ISO date (YYYY-MM-DD)

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$

Note that regex can constrain the shape of a date but not its real validity. This pattern happily accepts 2026-02-31. Range and calendar checks belong in code.

Phone number (loose, international-friendly)

^\+?[\d\s().-]{7,}$

Phone formats vary wildly across countries, so strict patterns reject real numbers. A loose pattern that checks for a plausible length and allowed characters is usually the right call, with normalization handled afterward.

Collapsing whitespace

\s+

Replace every match with a single space to collapse runs of spaces, tabs, and newlines. Combine it with a trim to tidy up messy user input.

Dialects differ

Regex is not one language. JavaScript, PCRE (PHP and many tools), Python, and the POSIX engines each support slightly different features. Lookbehind, named groups, and Unicode property escapes are not available everywhere. A pattern that works in Python may fail in an older JavaScript engine, so test in the environment that will actually run it.

Catastrophic backtracking

Some patterns are a performance trap. When a regex contains nested quantifiers that can match the same text in many ways, the engine may try an exponential number of combinations before giving up. A classic example is a pattern like (a+)+$ run against a long string of a characters followed by one that fails. On a short input it is instant; on a longer one it can hang for seconds or minutes.

The fix is to avoid overlapping quantifiers, prefer specific character classes over .*, and anchor patterns so the engine has fewer paths to explore. If a pattern feels slow on real data, that slowness is a warning, not noise.

A sane workflow

Build regex incrementally. Start with the smallest piece, confirm it matches, then add the next part. Test against both strings that should match and strings that should not, because false positives are the silent failures. Escape any literal characters that carry special meaning, since a stray dot or question mark changes behavior.

You can draft and verify patterns against sample input with the Regex Tester, and when you need to treat user input as literal text rather than a pattern, the Regex Escape tool handles the escaping for you.