regex for zip-code

^\d{5}(?:[-\s]\d{4})?$
  • ^ = Start of the string.
  • \d{5} = Match 5 digits (for condition 1, 2, 3)
  • (?:…) = Grouping
  • [-\s] = Match a space (for condition 3) or a hyphen (for condition 2)
  • \d{4} = Match 4 digits (for condition 2, 3)
  • …? = The pattern before it is optional (for condition 1)
  • $ = End of the string.

For the listed three conditions only, these expressions might work also:

^\d{5}[-\s]?(?:\d{4})?$
^\[0-9]{5}[-\s]?(?:[0-9]{4})?$
^\[0-9]{5}[-\s]?(?:\d{4})?$
^\d{5}[-\s]?(?:[0-9]{4})?$

Please see this demo for additional explanation.

If we would have had unexpected additional spaces in between 5 and 4 digits or a continuous 9 digits zip code, such as:

123451234
12345 1234
12345  1234

this expression for instance would be a secondary option with less constraints:

^\d{5}([-]|\s*)?(\d{4})?$

Please see this demo for additional explanation.

RegEx Circuit

jex.im visualizes regular expressions:

enter image description here

Test

const regex = /^\d{5}[-\s]?(?:\d{4})?$/gm;
const str = `12345
12345-6789
12345 1234
123451234
12345 1234
12345  1234
1234512341
123451`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Tags:

Regex