Regex Cheat Sheet: JavaScript Regular Expressions With UK and US Examples

JavaScript regex cheat sheet: character classes, quantifiers, groups, lookarounds, flags, UK postcode, US ZIP and phone patterns, and avoiding backtracking.

By the MakeItFlow team Updated 4 min read
Share LinkedIn X Facebook WhatsApp
Regex Cheat Sheet: JavaScript Regular Expressions With UK and US Examples

This regex cheat sheet covers the JavaScript flavour of regular expressions: character classes, anchors, quantifiers, groups, lookarounds and flags, each with a short example. Further down you'll find tested patterns for UK postcodes, US ZIP codes and phone numbers, the caveats that go with them, and how to avoid the catastrophic backtracking that can freeze a page or server.

Regular expressions look cryptic because they pack a lot into a few characters. Once you know the dozen or so building blocks, most patterns read left to right like a sentence. Every example here uses JavaScript syntax, which is what browsers, Node.js and most no-code tools with a "regex" field use. Other flavours (PCRE in PHP, Python's re, .NET) share almost all of the basics but differ at the edges, which we flag where it matters.

You can paste any pattern from this page into our free regex tester to see the matches highlighted live, with capture groups and a replace preview.

Key takeaways

  • In JavaScript, \\d and \\w only match ASCII digits and letters, and . skips line breaks unless you add the s flag.
  • Quantifiers are greedy by default; add ? after them (*?, +?) to make them match as little as possible.
  • Regex can check a postcode, ZIP code or phone number has the right shape, but not that it exists, so pair it with a lookup or a proper library.
  • Nested quantifiers such as (a+)+ can trigger catastrophic backtracking, so keep patterns simple, anchored and run them on limited-length input.

Regex cheat sheet: characters and classes

A character class matches one character from a set. These are the ones you'll use most:

Token Matches Example Matches in "Order #A12, 3 items"
. Any character except line breaks A.2 A12
\d A digit 0–9 \d+ 12, 3
\D Anything that isn't a digit \D+ Order #A, , , items
\w A letter, digit or underscore (ASCII) \w+ Order, A12, 3, items
\W Anything that isn't \w \W , #, ,
\s Whitespace: space, tab, line break and Unicode spaces \s+ the spaces
\S Any non-whitespace character \S+ Order, #A12,
[abc] Any one of a, b or c [#,] #, ,
[^abc] Any character except a, b or c [^\d\s]+ Order, #A, ,, items
[a-z] Any character in a range [A-Z]\d A1
\. \* \? A literal special character (escaped) \# or # #

Two JavaScript details catch people out. First, \d and \w are ASCII-only: \w won't match é or ł, even with the u flag. To match letters in any language, use a Unicode property escape such as \p{L} with the u or v flag. Second, . doesn't match a newline unless you add the s flag.

The characters that need escaping with a backslash to be matched literally are . * + ? ^ $ { } ( ) | [ ] \ /. Inside square brackets most of them lose their special meaning, but ], \, ^ (at the start) and - (in the middle) still need care.

Anchors and boundaries

Anchors don't match characters. They match positions.

Token Position Example Meaning
^ Start of the string (or of each line with m) ^Hello Text starts with "Hello"
$ End of the string (or of each line with m) \.pdf$ Ends with ".pdf"
\b Between a word character and a non-word character \bcat\b "cat" but not "category"
\B Not a word boundary \Bcat "cat" inside "bobcat"

For validation, always anchor both ends. \d{5} finds five digits anywhere in "123456789", while ^\d{5}$ only accepts a string that is exactly five digits.

Quantifiers: how many times

Token Meaning Example Matches
* 0 or more ab* a, ab, abbb
+ 1 or more ab+ ab, abbb
? 0 or 1 (optional) colou?r color, colour
{3} Exactly 3 \d{3} 123
{2,} 2 or more \d{2,} 12, 12345
{2,4} Between 2 and 4 [A-Z]{2,4} UK, GBP, ABCD
*? +? ?? Lazy: as few as possible <.+?> <b> rather than <b>bold</b>

Quantifiers are greedy by default. They grab as much as they can, then give characters back only if the rest of the pattern fails. On <b>bold</b>, the greedy <.+> matches the whole string, while the lazy <.+?> stops at the first >. A negated class is often clearer and faster than a lazy quantifier: <[^>]+> says "a <, then anything that isn't >, then >".

Groups, alternation and backreferences

Token Purpose Example
(abc) Capturing group, saved as $1, $2... (\d{2})/(\d{2})/(\d{4})
(?:abc) Non-capturing group, for grouping only (?:Mr|Mrs|Ms)\.?
(?<name>abc) Named capturing group (?<year>\d{4})
a|b Alternation: a or b jpe?g|png|webp
\1 Backreference to group 1 (\w)\1 finds doubled letters
\k<name> Backreference to a named group (?<q>['"]).*?\k<q>

In a replacement string, $1 inserts group 1 and $<name> inserts a named group. To turn a UK date into ISO format:

"23/10/2026".replace(/^(\d{2})\/(\d{2})\/(\d{4})$/, "$3-$2-$1");
// "2026-10-23"

Alternation has the lowest precedence of any operator, so ^cat|dog$ means "starts with cat" or "ends with dog". Write ^(?:cat|dog)$ if you mean "exactly cat or dog".

Lookahead and lookbehind

Lookarounds check what comes before or after a position without including it in the match.

Token Name Example Meaning
x(?=y) Positive lookahead \d+(?=%) A number followed by %
x(?!y) Negative lookahead \d+(?!%) A number not followed by %
(?<=y)x Positive lookbehind (?<=£)\d+(\.\d{2})? An amount after a £ sign
(?<!y)x Negative lookbehind (?<!£)\b\d+\b A number without a £ before it

Lookbehind is supported in all current major browsers and in Node.js. If you have to support very old browsers, test it first. A classic lookahead use is password rules, such as ^(?=.*\d)(?=.*[a-z]).{12,}$ for "at least 12 characters including a digit and a lowercase letter". Length matters far more than character rules, though, as our strong password guide explains.

JavaScript regex flags

Flags go after the closing slash (/pattern/gi) or as the second argument to new RegExp(). The MDN regular expressions guide lists eight:

Flag Name What it does
g global Finds all matches, not just the first
i ignoreCase Case-insensitive matching
m multiline ^ and $ match at the start and end of each line
s dotAll . also matches line breaks
u unicode Treats the pattern as Unicode code points and enables \p{...}
v unicodeSets An upgrade to u with set operations and string properties
y sticky Matches only from the position in lastIndex
d hasIndices Records start and end positions of each capture group

A common bug: a regex with the g flag remembers where it stopped in lastIndex. Calling .test() repeatedly on the same regex object can then return true, false, true for identical input. Drop the g flag for yes/no checks, or create the regex fresh each time.

Useful JavaScript methods

/^\d+$/.test("2026");                  // true or false
"a1b22c333".match(/\d+/g);             // ["1", "22", "333"]
[..."a1b22".matchAll(/(\d)+/g)];       // full match objects with groups
"a-b_c".replace(/[-_]/g, " ");         // "a b c"
"one, two;three".split(/[,;]\s*/);     // ["one", "two", "three"]

replaceAll() with a regex requires the g flag, or it throws a TypeError.

Common patterns (with honest caveats)

These patterns check that text has the right shape. None of them can tell you that a postcode, phone number or email address actually exists or belongs to the person typing it.

UK postcode

/^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$/i

This accepts the standard shapes: an outward code of one or two letters, a digit and an optional letter or digit (such as M1, LS6, SW1A), an optional space, then an inward code of one digit and two letters (1AA). It matches SW1A 1AA, m1 1ae and LS61AB.

Caveats:

  • It allows impossible postcodes. Some letters never appear in certain positions, and many valid-looking combinations aren't in use. Stricter patterns exist, but they're long and still can't confirm a real address.
  • Normalise before you store. Uppercase the input, remove all spaces, then insert one space before the last three characters. ls61ab becomes LS6 1AB.
  • Special cases. GIR 0AA (historically Girobank) and British Forces (BFPO) addresses don't fit the pattern. Overseas territories use their own formats.
  • To confirm a postcode exists, check it against an address lookup service or Royal Mail's Postcode Address File data via a licensed provider.

US ZIP code

/^\d{5}(?:-\d{4})?$/

This accepts a five-digit ZIP code such as 90210 and the ZIP+4 form 90210-1234. Like the postcode pattern, it only checks the shape: many five-digit numbers aren't real ZIP codes, so use an address lookup if you need to confirm one exists.

UK mobile number

/^(?:\+44|0)7\d{9}$/

Strip spaces, dashes and brackets first (value.replace(/[\s()-]/g, "")). This accepts 07700900123 and +447700900123. Most UK numbers are 11 digits including the leading 0, but some older geographic numbers are shorter, and people type them in many ways, including the common but awkward +44 (0)20 style. For anything beyond a basic mobile check, use a maintained library such as Google's libphonenumber rather than a home-made regex. It knows which ranges are allocated and formats numbers consistently.

Email address

/^[^\s@]+@[^\s@]+\.[^\s@]+$/

This only checks for "something@something.something" with no spaces. Fully RFC-compliant email regexes are enormous and still can't tell you if the mailbox exists. The only real test is sending a confirmation email. Before you send at volume, run the domain through our email deliverability checker.

More quick patterns

Need Pattern Notes
UK date dd/mm/yyyy ^(0[1-9]|[12]\d|3[01])\/(0[1-9]|1[0-2])\/\d{4}$ Allows 31/02; check real dates in code
Price in pounds ^£?\d{1,3}(,\d{3})*(\.\d{2})?$ Matches £1,250.00 and 99
Hex colour ^#(?:[0-9a-f]{3}){1,2}$ with i #fff, #1A2B3C
URL slug ^[a-z0-9]+(?:-[a-z0-9]+)*$ See our slug generator
UUID ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ with i Any version
Trim spaces ^\s+|\s+$ with g Or just use .trim()

Regex shows up in server config too, for example in Apache RewriteRule and RedirectMatch lines. Our .htaccess guide has working redirect patterns. Note that robots.txt is not regex: it only supports * and $ wildcards, which our robots.txt tester handles correctly.

Catastrophic backtracking: the regex that freezes everything

JavaScript, like PHP, Python and most languages, uses a backtracking regex engine. When part of a pattern fails, the engine goes back and tries another way of splitting the text. Usually that's instant. With certain patterns and inputs, the number of possible paths doubles with every extra character.

The OWASP page on ReDoS (regular expression denial of service) gives typical "evil" patterns:

  • (a+)+$
  • ([a-zA-Z]+)*$
  • (a|aa)+$
  • (a|a?)+$

All of them repeat a group that itself contains a repetition or overlapping alternatives. On a string of a characters ending in something that doesn't match, OWASP shows that ^(a+)+$ has 16 possible paths for four characters and 65,536 for seventeen. A few dozen characters can lock up a browser tab or a Node.js server, because the matching blocks the thread. This isn't theoretical: Cloudflare's global outage on 2 July 2019 was caused by a single WAF rule whose regex backtracked excessively.

How to avoid it

  1. Never nest quantifiers on overlapping content. (\w+\s?)+ is risky. Rewrite it as \w+(?:\s\w+)*, where each step can only match one way.
  2. Make alternatives mutually exclusive. (a|aa)+ can match the same text many ways. a+ can't.
  3. Prefer negated classes to .*. "[^"]*" is faster and safer than ".*?".
  4. Anchor patterns so the engine doesn't retry from every starting position.
  5. Limit input length before running a regex on user-supplied text. A postcode doesn't need 10,000 characters.
  6. Never build a regex from user input without escaping it. If users can supply patterns, run them in a worker with a timeout, or on the server use a linear-time engine such as RE2.

Our regex tester runs matching in a background worker and stops it after two seconds, so a runaway pattern shows a warning instead of freezing your browser. That makes it a safe place to try a pattern against long, awkward input before it goes live.

A quick workflow for writing a new pattern

  1. Collect 5–10 real examples that should match and 5 that shouldn't, including edge cases.
  2. Write the simplest pattern that matches the first good example.
  3. Anchor it with ^ and $ if you're validating a whole value.
  4. Test it against every example, then tighten or loosen one piece at a time.
  5. Add a comment in your code explaining what the pattern accepts and why.
  6. Test a long, nearly matching string to check for backtracking.

If you find yourself writing regexes to tidy up the same exports or form submissions every week, that's usually a sign the job could be automated end to end. Make It Flow maps the workflow first and then decides where a pattern, a library or a person should make the call. Talk to us if that sounds familiar. More developer utilities are collected on our free tools for web development page.

FAQ

What is regex used for?

Regex (regular expressions) describes text patterns. It's used to validate input such as postcodes, to search logs and documents, to find and replace across files, to split or extract data from exports, and in server rules such as redirects. Most programming languages, code editors, spreadsheets and automation tools support it in some form.

Is JavaScript regex the same as PCRE or Python?

The core syntax is shared: classes, quantifiers, groups, anchors and lookarounds work the same way. Differences appear at the edges. Possessive quantifiers and atomic groups exist in PCRE but not in standard JavaScript, flag names differ, and Python uses (?P<name>...) for named groups. Test patterns in the flavour you'll actually run.

How do I match any character including new lines?

Add the s (dotAll) flag, so . also matches line breaks: /start.*end/s. Without the flag, a common workaround is [\s\S], which means "any whitespace or any non-whitespace", in other words any character at all. Both work in all current browsers and Node.js.

What does ?: mean in regex?

(?:...) is a non-capturing group. It groups part of a pattern so you can apply a quantifier or alternation to it, without saving the match as $1, $2 and so on. Use it when you need grouping but not the captured value. It keeps group numbering simple and is slightly more efficient.

Can regex validate a UK postcode properly?

Only partly. A pattern such as ^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$ checks the general shape, but it accepts postcodes that don't exist and rejects special cases like BFPO addresses. To be sure an address is real, use a postcode lookup backed by Royal Mail data.

Why is my regex so slow?

Usually because of catastrophic backtracking: nested quantifiers like (a+)+ or overlapping alternatives give the engine an exponential number of ways to try a failing match. Rewrite the pattern so each character can only be matched one way, anchor it, replace .* with negated classes and limit the input length.

#regex #regular expressions #javascript #web development

More guides for your industry

Free checklist (PDF)

Free web developers website checklist

31 practical checks for web developers: website speed and mobile, Google Business Profile and reviews, email security, booking and enquiry handling, and AI search visibility. Each one says why it matters, and many link to a free tool that checks it.

We email you the PDF and nothing else unless you tick the box. See the privacy policy.

Written by the MakeItFlow team

We build the website audit these guides are based on. Every fact is checked against the primary sources listed above and this guide was last reviewed on 25 October 2026 . How we research and check

Share LinkedIn X Facebook WhatsApp

Check your own site in 30 seconds

Run a free audit covering speed, SEO, DNS, email authentication and security headers — and get a prioritised fix list.

Weekly newsletter

One practical website fix, every week

New guides on speed, SEO, email deliverability and security — straight to your inbox. No spam, unsubscribe in one click.

Keep reading