Validate a US ZIP code
Accept a standard 5-digit US ZIP code or the extended ZIP+4 form, and reject anything that isn't one of those two shapes.
Last updated
Matches
- 90210
- 12345-6789
Doesn’t match
- 1234
- 123456
Why it’s written this way
\d{5} matches the base 5-digit ZIP code every US address needs, and the optional non-capturing group (?:-\d{4})? adds support for the ZIP+4 extension — a dash followed by four more digits — without requiring it.
Because the extension is wrapped in a '?', both '90210' and '12345-6789' satisfy the same anchored pattern, which is the pair of formats USPS actually uses on mail and shipping forms.
Edge cases to know
- →It checks shape only — '00000' and '99999' both match even though neither is an assigned ZIP code.
- →It doesn't know which ZIP codes exist or which state or city they belong to; matching that up needs an actual USPS ZIP database.
- →Some address forms accept a ZIP+4 typed with a space instead of a dash ('12345 6789') — this pattern doesn't, so normalize the separator first if your form allows that.
Part by part
- ^\d{5}
- The five-digit base code, anchored at the start so nothing precedes it.
- (?:-\d{4})?
- The optional ZIP+4 extension: a hyphen and four more digits identifying a delivery segment. Optional because most addresses are written without it.
- $
- Anchored at the end, so a longer number cannot pass by having a valid ZIP at its front.
Common mistakes
^\d{5}$Rejecting ZIP+4 outright turns away a correctly written address. The extension is more precise, not less valid, and users who have it will type it.
^\d{5}(?:-\d{4})?$^\d{5}(-\d{4})?$A capturing group works but adds an entry to every match result that nothing uses. Prefer non-capturing groups when you are only grouping for the quantifier.
^\d{5}(?:[- ]?\d{4})?$Allowing a space or no separator accepts a nine-digit run that could equally be a mistyped phone number, and stores the same address in several forms.
Questions
Should I store the leading zero?
Yes, and store the whole thing as text. Several New England ZIP codes begin with zero, and parsing them as numbers silently turns 02134 into 2134 — a classic bug that only shows up for customers in one region.
Does a match mean the ZIP exists?
No. The Postal Service assigns and retires codes, and the pattern knows nothing about the current list. Validate against USPS data if delivery accuracy matters.
What does the +4 part actually identify?
A delivery segment — one side of a street, a floor of a building, or a group of post office boxes. It improves sorting accuracy but is rarely required, which is why it should stay optional.
Can I infer the state from a ZIP code?
Broadly, since codes are assigned geographically from east to west, but a handful straddle state lines. Use it to prefill and let the user correct it rather than overriding what they entered.
Why do some forms reject a ZIP+4 that is printed on the envelope?
Usually because the field was validated with a five-digit-only pattern and nobody tested the longer form. It is worth checking your own form against both, because the user reading the extension off a label has no way to know which half you wanted.