[NTTP]

Regex Builder

Describe what you want to match in plain English. Get a working regex for your language, explained piece by piece, checked against your own test cases.

Plain English is fine. Be as specific as you can about the format.

Optional

Optional but recommended. One example per line.

Optional

Optional. One example per line.

Syntax differs between engines (named groups, lookbehind support), so pick the one you are actually using.

Free to try, no sign-up needed

Your text isn't stored. It's sent to Anthropic to generate your result, then discarded. Privacy

Prefer to write it yourself? Use the free prompt.

New to this? Read the guide.

What it produces

Real output from this tool, not a mock-up.

What went in

What you want to match
A UK postcode in a longer piece of text. Should handle the normal formats with or without the space, and be case insensitive.
Examples that should match
SW1A 1AA, EC1A1BB, m1 1ae, B33 8TH, CR2 6XH, DN55 1PT
Examples that should NOT match
12345, SW1A 1AAA, ABCDE, 1A1 A1A
Regex flavor
JavaScript

Pattern

/\b(GIR 0AA|[A-PR-UWYZ][A-HK-Y0-9][A-HJKPSTUW0-9]?[ABEHMNPRVWXY0-9]?\s?[0-9][ABD-HJLNP-UW-Z]{2})\b/gi

How it works

UK postcodes come in a handful of shape variants (like SW1A 1AA, EC1A 1BB, M1 1AE, B33 8TH, CR2 6XH, DN55 1PT), all built the same way: an outward code (one or two letters, then one or two digits, sometimes followed by a letter) and an inward code (always one digit followed by two letters). This pattern is the standard shape used by the UK government's own postcode regex, adapted for JavaScript. Piece by piece: - \b : a word boundary, so the postcode has to start at the edge of a word rather than in the middle of some longer alphanumeric string. - (GIR 0AA| ... ) : special-cases the one postcode that doesn't follow the normal rules (Girobank's), then falls through to the general pattern. - [A-PR-UWYZ] : first letter of the area code. Excludes Q, V, X which never start a real postcode. - [A-HK-Y0-9] : second character, either a letter (with I excluded, which never appears here) or a digit, since areas like B, M, or EC1 vary in length. - [A-HJKPSTUW0-9]? : an optional third character (covers things like the '1A' in SW1A). - [ABEHMNPRVWXY0-9]? : an optional fourth character (covers the 'A' in EC1A). - \s? : an optional single space between outward and inward code, so both 'SW1A 1AA' and 'EC1A1BB' work. - [0-9] : the digit that always starts the inward code. - [ABD-HJLNP-UW-Z]{2} : the two letters that finish the postcode, excluding C, I, K, M, O, V which never appear in that position. - \b : closing word boundary. Checked against your examples: SW1A 1AA, EC1A1BB, m1 1ae, B33 8TH, CR2 6XH, and DN55 1PT all match (case doesn't matter thanks to the i flag). 12345 and ABCDE fail because they don't have the letter/digit structure at all. SW1A 1AAA fails because the trailing letters group is locked to exactly two characters and the trailing 'A' left over won't complete a fresh valid postcode. 1A1 A1A fails since it starts with a digit, which no real outward code does. The 'ZZ99 9ZZ is not real...' line does match on the ZZ99 9ZZ part, but as you noted that one is intentionally skipped since it's about realism, not format, and a regex can't know which postcodes are actually allocated. Gotcha worth knowing: this checks structure only. It'll accept plenty of strings that look like postcodes but were never issued (Royal Mail's actual list of valid outward codes changes over time), so if you need to confirm a postcode genuinely exists you'd need to check it against an up-to-date official list, not just this pattern.

When to use it

Use this when you know what you want to match and do not want to spend forty minutes on it. Describe it in plain English, give examples that should and should not match, and you get a pattern for your flavour with a piece-by-piece explanation.

Common questions

Why does it ask for examples?
Because they are what makes the pattern correct rather than plausible. The should-not-match list matters most: without it you get something that matches your examples and a great deal else. Test the result against your own data before shipping it.
Does the flavour setting matter?
Yes. JavaScript, Python, PCRE and POSIX differ on lookbehind, named groups, escaping and Unicode handling. A pattern copied between them often works until it silently does not.
Will it explain the pattern?
Piece by piece, which is the part worth reading. A regex you cannot read is one you cannot safely change in six months, and the explanation is usually more valuable than the pattern itself.
Is it free?
You can run it three times a day with no account. Signing in gives you renewing monthly credits, and this tool costs one credit per run with the one-click refinements included.

Similar tools

All Developers