International Postal Code Formats: A Quick Reference

Postal codes look deceptively simple until you try to validate them across borders. A field that accepts 90210 without complaint will reject SW1A 1AA or M5V 2T6 if the validation logic only knows about US ZIP codes. This guide covers the formats used in the most common countries, the regex patterns that match them, and the handful of places that don't use postal codes at all.

Why Postal Code Formats Differ So Much

Postal systems evolved independently before any international standard existed. The result is a patchwork: some countries use pure digits, others mix letters and numbers, and a few use entirely different separators or positional rules. The Universal Postal Union publishes guidance, but each national postal authority sets its own spec.

Length alone varies from two digits (parts of Iceland) to ten characters (Brazil's extended format). Case matters in some systems but not others. Several countries share a format but use completely different assignment logic underneath.

Understanding the structure helps you write validation that's strict enough to catch typos but loose enough to accept legitimate codes from anywhere on your user's signup form.

Common Country Formats at a Glance

The table below covers countries that appear most frequently in international shipping and testing datasets. The regex patterns are written to match the postal code in isolation, so strip whitespace before applying them.

CountryExampleFormat descriptionRegex pattern
United States90210 / 90210-43215 digits, optional +4 extension^\d{5}(-\d{4})?$
United KingdomSW1A 1AAAN NAA or AAN NAA etc.^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$
CanadaM5V 2T6ANA NAN (letter-digit alternating)^[A-Z]\d[A-Z]\s?\d[A-Z]\d$
Germany803315 digits^\d{5}$
France750085 digits^\d{5}$
Japan150-00017 digits with hyphen after first 3^\d{3}-\d{4}$
Australia20004 digits^\d{4}$
Netherlands1234 AB4 digits + 2 letters^\d{4}\s?[A-Z]{2}$
Brazil01310-1008 digits with hyphen after first 5^\d{5}-\d{3}$
India1100016 digits^\d{6}$
Mexico066005 digits^\d{5}$
Sweden113 215 digits, sometimes written with a space^\d{3}\s?\d{2}$

For a deeper look at how these fit into full address strings, see how address formats vary by country.

Writing Regex Patterns for Postal Code Validation

A few principles make postal code regex more reliable in practice.

Case normalization first. UK, Canadian, and Dutch codes use uppercase letters by convention, but users type them in lowercase all the time. Normalize to uppercase before running validation rather than writing case-insensitive patterns. sw1a 1aa becomes SW1A 1AA, which your regex can match cleanly.

Treat the space as optional. UK, Canadian, Dutch, and Swedish codes traditionally include a space, but many databases and form fields strip it. Write your pattern to accept both M5V2T6 and M5V 2T6. The \s? placeholder handles this without needing two separate patterns.

The UK format is genuinely tricky. The outward code (the first half) can be one or two letters, one or two digits, and optionally a trailing letter. Valid outward codes include W1, W1A, SW1, SW1A, EC1A, and EC1. A simplified pattern like ^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$ covers most real addresses but doesn't rule out every impossible combination. For thorough UK validation, a lookup against the Royal Mail's postcode database is more reliable than regex alone.

US extended ZIP codes. The ZIP+4 format (12345-6789) is optional and often omitted by users. Your validation should accept both the 5-digit and the hyphenated 9-digit form rather than requiring one or the other.

Don't conflate format with existence. A code can match the regex perfectly and still not exist. Regex confirms shape, not validity. For generating realistic test data that passes deeper checks, see how to generate realistic test addresses for forms.

Countries That Don't Use Postal Codes

Not every country has a postal code system. Some rely on city and street addressing alone; others have codes only for major cities or P.O. boxes.

Countries with no national postal code system (as of this writing) include:

When you're building address forms for a global audience, the postal code field should never be marked as globally required. A sensible approach: require it only when the selected country has a well-established system, and leave it optional otherwise.

Validation Edge Cases Worth Knowing

Standard patterns handle the common case. The edge cases are where things break quietly.

UK Crown dependencies. Jersey (JE), Guernsey (GY), and the Isle of Man (IM) use UK-style postcodes but are not part of the UK postcode system. A form that accepts UK addresses but blocks JE2 3AB will confuse a lot of users.

Canadian codes exclude certain letters. The letters D, F, I, O, Q, and U never appear in Canadian postal codes because they're too easy to confuse with digits. A regex that allows all letters will accept D0D 0D0 even though it can't be a real code. The strict pattern is ^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV]\s?\d[ABCEGHJ-NPRSTV]\d$.

Numeric-only codes with leading zeros. French department 01 (Ain) produces codes like 01000. Database columns typed as integers silently drop that leading zero. Store postal codes as strings, always.

Alphanumeric confusion in OCR and manual entry. The letter O and digit 0 are common mix-ups, as are I/1 and S/5. For test data intended to exercise OCR pipelines, generating codes that include these ambiguous characters deliberately is worth doing. More on testing edge cases like these at address edge cases that break forms.

Building a Country-Aware Validator

A single global regex is the wrong tool. The practical approach is a lookup object keyed by ISO 3166-1 alpha-2 country code, where each entry holds the pattern and any normalization steps needed.

const postalPatterns = {
  US: { pattern: /^\d{5}(-\d{4})?$/, normalize: (v) => v.trim() },
  GB: { pattern: /^[A-Z]{1,2}\d[A-Z\d]?\s?\d[A-Z]{2}$/, normalize: (v) => v.trim().toUpperCase() },
  CA: { pattern: /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV]\s?\d[ABCEGHJ-NPRSTV]\d$/, normalize: (v) => v.trim().toUpperCase() },
  DE: { pattern: /^\d{5}$/, normalize: (v) => v.trim() },
  JP: { pattern: /^\d{3}-\d{4}$/, normalize: (v) => v.trim() },
  // add more as needed
};

function validatePostalCode(country, value) {
  const entry = postalPatterns[country];
  if (!entry) return true; // unknown country, skip validation
  const normalized = entry.normalize(value);
  return entry.pattern.test(normalized);
}

Countries absent from the lookup pass through without an error, which handles the no-postal-code case gracefully. For more background on what a technically valid address looks like beyond the postal code, see what makes an address valid.

Frequently Asked Questions

Do postal codes and ZIP codes mean the same thing?

ZIP code is the US-specific term, originally standing for Zone Improvement Plan. "Postal code" is the generic international term. Most countries use postal code or postcode, though the underlying systems work differently everywhere.

Can two countries share the same postal code format?

Yes, and it causes real problems. Germany and France both use 5-digit numeric codes, so 75008 is a valid French code and could theoretically collide with a German one if you're not filtering by country first. Always validate in the context of the country field, not the postal code field alone.

Why do some UK postcodes have letters at the end?

The inward code (second half of a UK postcode) always ends in two letters. The letters indicate a specific street segment or building cluster within the district. The Royal Mail assigns them; they're not derived from place names or alphabetical logic.

Is it safe to use synthetic postal codes in automated tests?

Synthetic codes in the right format are appropriate for most testing purposes: form validation, UI rendering, and integration tests that don't hit live geocoding APIs. If your test pipeline calls a shipping rate calculator or address verification service, use known sandbox codes from the provider's documentation instead, since real-looking fake codes may resolve unexpectedly.