★ Identity & contact · regex
Regex for US Phone Number
Accepts US and Canadian numbers written as (415) 555-2671, 415-555-2671, 415.555.2671 or with +1. Area codes and exchanges can't start with 0 or 1 under the North American Numbering Plan, so those are rejected.
- Runs in your browser
- No signup
Try the us phone number pattern
Read it in plain English (best-effort)
- ^start of a line
- (?:start a group (not captured)
- +the character '+'
- ?the previous is optional
- 1the character '1'
- [ .-]one character from: space, '.', '-'
- ?the previous is optional
- )end of group
- ?the previous is optional
- (the character '('
- ?the previous is optional
- (start capture group 1
- [2-9]one character from: 2–9
- [0-9]one character from: 0–9
- {2}exactly 2 of the previous
- )end of group
- )the character ')'
- ?the previous is optional
- [ .-]one character from: space, '.', '-'
- ?the previous is optional
- (start capture group 2
- [2-9]one character from: 2–9
- [0-9]one character from: 0–9
- {2}exactly 2 of the previous
- )end of group
- [ .-]one character from: space, '.', '-'
- ?the previous is optional
- (start capture group 3
- [0-9]one character from: 0–9
- {4}exactly 4 of the previous
- )end of group
- $end of a line
One sample per line works well with the m flag on anchored patterns.
The pattern, piece by piece
/^(?:\+?1[ .-]?)?\(?([2-9][0-9]{2})\)?[ .-]?([2-9][0-9]{2})[ .-]?([0-9]{4})$/| Part | What it does |
|---|---|
(?:\+?1[ .-]?)? | optional country code 1 or +1 |
\(?([2-9][0-9]{2})\)? | group 1: area code, optionally in parentheses |
[ .-]? | optional separator |
([2-9][0-9]{2}) | group 2: exchange code |
([0-9]{4}) | group 3: line number |
What it accepts and rejects
Every sample below is checked automatically in JavaScript and Python. The tester above is preloaded with all of them, one per line.
| Should match | |
|---|---|
(415) 555-2671 | ✓ |
415-555-2671 | ✓ |
415.555.2671 | ✓ |
4155552671 | ✓ |
+1 415 555 2671 | ✓ |
1-415-555-2671 | ✓ |
| Should not match | |
|---|---|
(115) 555-2671 | ✗ |
415-155-2671 | ✗ |
555-2671 | ✗ |
415-555-267 | ✗ |
+44 20 7946 0958 | ✗ |
415-555-26711 | ✗ |
Copy it into your code
RE2-safeNo lookarounds or backreferences, so the same pattern works in Go's RE2 engine and in Rust's regex crate.
const usPhoneRe = /^(?:\+?1[ .-]?)?\(?([2-9][0-9]{2})\)?[ .-]?([2-9][0-9]{2})[ .-]?([0-9]{4})$/;
export function isValidUsPhone(value) {
return usPhoneRe.test(value.trim());
}When not to use regex for this
For anything international, or to store numbers properly, use libphonenumber (Google's library, ported to most languages). Normalise to E.164 and store that, not the formatted string.
Questions engineers actually ask
Does it allow unbalanced parentheses like (415 555-2671?
Does it validate that the number exists?
What is catastrophic backtracking?
More identity & contact patterns
- E.164 Phone NumberInternational numbers in E.164: +, country code, up to 15 digits.^\+[1-9][0-9]{6,14}$
- US ZIP CodeFive-digit ZIP codes with an optional ZIP+4 suffix.^[0-9]{5}(?:-[0-9]{4})?$
- Username3–16 characters, starts with a letter, letters, digits and underscores only.^[a-zA-Z][a-zA-Z0-9_]{2,15}$
- Strong Password12+ characters with lowercase, uppercase, a digit and a symbol.^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{12,}$
- Credit Card Number Format16-digit cards in groups of four, and 15-digit Amex in 4-6-5. Format only.^(?:(?:\d{4}[ -]?){3}\d{4}|3[47]\d{2}[ -]?\d{6}[ -]?\d{5})$
Or browse the full regex library.
More from the workbench
Fine print
Tools: on the house.
Engineer: by the hour.
The regex was free. Code that doesn't need one is the upgrade: typed schemas, validated once at the edge, trusted everywhere after.
I'm Himanshu, an AI and full-stack engineer. I build MVPs, AI agents and the growth plumbing around them for early-stage startups.
