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.
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.