Phone Number Regex
Validates common North American phone number formats, accepting optional country code, parentheses, dots, dashes, or spaces as separators.
Regex Pattern
^\+?1?[-.\s]?\(?([0-9]{3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| \+? | Optional leading plus sign for the country code |
| 1? | Optional literal 1 country code for North America |
| [-.\s]? | Optional separator: a hyphen, dot, or whitespace character |
| \(? | Optional opening parenthesis around the area code |
| ([0-9]{3}) | Capture group for the 3-digit area code |
| \)? | Optional closing parenthesis around the area code |
| ([0-9]{4}) | Capture group for the final 4-digit line number |
Detailed Explanation
What it does
This pattern validates 10-digit North American Numbering Plan phone numbers, optionally prefixed with a country code, and allows the area code, exchange, and line number to be separated by spaces, dots, dashes, or wrapped in parentheses.
Why it works
Each separator between the digit groups is made optional with ? so the same pattern matches compact digit-only input like 1234567890 as well as formatted input like (123) 456-7890, because every punctuation character is treated as optional rather than required. The three capture groups isolate the area code, exchange, and line number so calling code can reformat or store them separately.
Common use cases
- Validating a phone number field in a signup or checkout form
- Normalizing user-entered phone numbers before storing them in a database
- Extracting area code, exchange, and line number via capture groups for formatting
- Filtering text or logs for strings that look like US/Canada phone numbers
Edge cases
- Numbers with the leading country code and a plus sign, like +11234567890, are matched
- Mixed separators such as (123).456-7890 are still accepted because each separator is evaluated independently
- A 9-digit or 11-digit number without a valid country code prefix will fail to match
- Extensions like x123 at the end are not supported and will cause the match to fail
Limitations
- Only supports North American Numbering Plan (NANP) formats, not international numbers in general
- Does not validate that the area code or exchange corresponds to a real, assigned range
- Does not support extensions, vanity numbers with letters, or E.164-only formats without adaptation
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const phoneRegex = /^\+?1?[-.\s]?\(?([0-9]{3})\)?[-.\s]?([0-9]{3})[-.\s]?([0-9]{4})$/;
console.log(phoneRegex.test('(123) 456-7890')); // trueCommon Mistakes
Assuming this pattern validates international phone numbers from any country
Fix: Use a dedicated library like libphonenumber for international numbers; this regex targets NANP formats only
Making every separator required instead of optional, which rejects valid unformatted input like 1234567890
Fix: Keep separators optional with ? so both formatted and plain digit strings are accepted
Forgetting that parentheses must be balanced when present but the regex allows an opening paren without a matching closing one
Fix: For stricter validation, use a non-capturing alternation that requires both parentheses together or neither
Performance Notes
- All quantifiers are bounded ({3}, {4}) or single-optional (?), so there is no catastrophic backtracking risk
- Anchoring with ^ and $ ensures the whole string is validated rather than a substring
- Capture groups add minor overhead versus non-capturing groups; use (?:...) instead if you don't need the extracted parts
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |