Skip to content

US ZIP Code Regex (5-Digit and ZIP+4)

Accept a five-digit US ZIP code, with or without the four-digit ZIP+4 add-on after a hyphen.

JavaScript
103 characters

One case per line; the m flag makes ^ and the end anchor work line by line.

Link optionspattern only

The address bar holds the pattern, flags and replacement, so Copy link shares them. Your test text stays out of it unless you include it (up to 2,000 characters), because it may be private. Nothing is sent to a server.

Matches

6matches

The first is “90210”, at position 0.

Groups
none
Characters matched
40 of 103
What the pattern meansHover or tap a part to see it in the pattern and what it matched
How this works: Method, 4 sources, Checked against 1 worked example,

How this works

Method

Your pattern runs in your own browser’s JavaScript engine, in a background worker that is stopped after 1.5 seconds, so a pattern that backtracks catastrophically can’t freeze the page. The explanation comes from our own parser of the ECMAScript pattern grammar, checked against the engine; what each part matched is found by wrapping that part in one more group and running the pattern again. Conversions to other flavours only rewrite the syntax and list what their documentation says works differently.

How it’s tested

One worked example for this page is checked by automated tests before every release: given the inputs, the tool must show the expected answer.

Changes

  • First published, with a library of 19 common patterns and their test cases.

How we make toolsReport a mistake

Worked example

Take 90210, the first case in the tester. Reading the pattern left to right, each part takes its share of the text:

  1. ^The start of the text (matches a position, no characters)
  2. \d{5}Exactly five digits (0–9) matches 90210
  3. (?:-\d{4})?A group (not captured), optional (zero or one time): (matches a position, no characters)
  4. $The end of the text (matches a position, no characters)

How the ZIP code regex works

\\d{5}\ asks for exactly five digits, the ZIP code the US Postal Service introduced in 1963. The group \(?:-\d{4})?\ adds the ZIP+4 extension: a hyphen and four more digits, and the question mark after the group makes the whole extension optional. Because the hyphen sits inside the group, "90210-" fails: either the full add-on is there or none of it is.

The anchors matter more here than in most patterns. Without the caret and the dollar sign, "1234567" would contain a five-digit run and pass a search. With them, the string must be exactly a ZIP code and nothing else.

The most common ZIP bug isn't in the regex at all: storing the code as a number. ZIP codes in New England and parts of New Jersey and New York start with 0, and a numeric column or \parseInt\ turns 02134 into 2134. Keep ZIP codes as text, and if you receive four-digit values from an old spreadsheet, pad them back with \padStart(5, '0')\ before testing.

  • ZIP Codes (Zone Improvement Plan) were introduced on 1 July 1963 as five digits, the first naming a region of the country. Source: ZIP Code (Wikipedia).
  • ZIP+4, added in 1983, is the five-digit code followed by a hyphen and four digits that narrow the location further. Source: ZIP Code (Wikipedia).
  • The lowest ZIP Code is 00501 in Holtsville, New York, used only by an IRS centre, which is why leading zeros must be kept. Source: ZIP Code (Wikipedia).

Test cases

Every case runs as an automated test of this page’s pattern, so the table can’t drift from what the pattern really does.

Test cases for the US ZIP code regex
TextResultWhy
90210Passesfive digits
00501Passesthe lowest ZIP code, Holtsville, New York: the zeros matter
02134Passesa Boston ZIP code starting with 0
10001-1234PassesZIP+4 with its hyphen
20500-0003PassesZIP+4 whose add-on starts with zeros
99950Passesone of the highest, in Alaska
9021Failsfour digits, perhaps a lost leading zero
902101Failssix digits
90210-12Failsthe add-on needs four digits
90210 1234Failsa space instead of the hyphen
90210-Failsa hyphen with nothing after it
902101234Failsnine digits with no hyphen
SW1A 1AAFailsa UK postcode, a different format

What it doesn’t check

  • A matching code may not exist; only the USPS address data can say whether 12345 is in use.
  • It doesn’t accept a space or no separator before the +4 part; normalise those inputs first if your form allows them.
  • It is US-only: Canadian, UK and other postcodes use letters and different layouts, so use a country-specific pattern for each.
  • Military APO and FPO addresses use ordinary-looking five-digit codes, so the pattern can’t tell them apart and doesn’t need to.

The same pattern in other languages

Converted automatically from the JavaScript version; the tester above always runs JavaScript.

The pattern in Python, PCRE, Go, Java and .NET
FlavourPatternNotes
Python(?a)^\d{5}(?:-\d{4})?\Z
PCRE^\d{5}(?:-\d{4})?\z
Go^\d{5}(?:-\d{4})?$
Java^\d{5}(?:-\d{4})?\z
.NET^\d{5}(?:-\d{4})?\zIn .NET, \d and \w match any Unicode digit or letter. Pass RegexOptions.ECMAScript, or write [0-9] and [A-Za-z0-9_], for JavaScript’s ASCII-only meaning.

Sources

Frequently Asked Questions

What regex matches a US ZIP code?

Five digits, optionally followed by a hyphen and four more digits, anchored at both ends. That covers both the basic ZIP code and ZIP+4.

Why did my ZIP code lose its first digit?

It was stored or parsed as a number, which drops leading zeros. Treat ZIP codes as text everywhere, from the form field to the database column.

Does a matching ZIP code mean the address is real?

No. The pattern checks only the shape. Use an address verification service built on USPS data if you need to know a code is in use or matches the city.