Phone Number Regex
The E.164 phone regex pair — an optional-plus gate and the strict international form, with honest libphonenumber advice and live testing.
Pattern variants
Pragmatic
/^\+?[1-9]\d{1,14}$/
What it matches
E.164 digit strings: an optional +, a non-zero first digit, 2-15 digits total.
What it deliberately doesn't
Formatting — spaces, hyphens, parentheses — and every national dialling form; strip separators before gating.
Strict
/^\+[1-9]\d{1,14}$/
What it matches
Full international E.164 form only: a mandatory + followed by 2-15 digits.
What it deliberately doesn't
Bare national digit strings without the + prefix.
Verified vectors
| Input | Pragmatic | Strict | Note |
|---|---|---|---|
"+14155552671" | ✓ matches | ✓ matches | |
"14155552671" | ✓ matches | ✗ no match | digits without + — strict requires the prefix |
"+49301234567" | ✓ matches | ✓ matches | |
"+861234567890123" | ✓ matches | ✓ matches | 15 digits — the E.164 maximum |
"+8612345678901234" | ✗ no match | ✗ no match | 16 digits — over the E.164 maximum |
"+04155552671" | ✗ no match | ✗ no match | country codes never start with 0 |
"(415) 555-2671" | ✗ no match | ✗ no match | national formatting — strip separators first |
"+1 415 555 2671" | ✗ no match | ✗ no match | spaces are formatting, not E.164 |
"555-2671" | ✗ no match | ✗ no match | local fragment |
"0044 20 7946 0958" | ✗ no match | ✗ no match | trunk-prefix national form |
Usage by language
JavaScript
Machine-verified/^\+?[1-9]\d{1,14}$/
/^\+[1-9]\d{1,14}$/
Python
Machine-verifiedre.compile(r"^\+?[1-9]\d{1,14}$")
re.compile(r"^\+[1-9]\d{1,14}$")
Java
Syntax-reviewed — not machine-verifiedPattern.compile("^\\+?[1-9]\\d{1,14}$")
Pattern.compile("^\\+[1-9]\\d{1,14}$")
Go
Syntax-reviewed — not machine-verifiedregexp.MustCompile(`^\+?[1-9]\d{1,14}$`)
regexp.MustCompile(`^\+[1-9]\d{1,14}$`)
C#
Syntax-reviewed — not machine-verifiednew Regex(@"^\+?[1-9]\d{1,14}$")
new Regex(@"^\+[1-9]\d{1,14}$")
PHP
Syntax-reviewed — not machine-verified'/^\\+?[1-9]\\d{1,14}$/'
'/^\\+[1-9]\\d{1,14}$/'
Caveats
- E.164 gating only — for real-world numbers (national formats, extensions, per-region validity) use libphonenumber.
- Local conventions differ by country; there is no one universal phone regex — normalize to E.164 first.
Related patterns
Do it offline:$ grep -E '^\+?[1-9][0-9]{1,14}$' numbers.txt
How to use it
- Strip spaces, dots, hyphens and parentheses before matching — formatting is presentation; this gate reads digits plus the optional +.
- Keep the pragmatic variant for stored values that may lack a prefix; go strict when every number must carry its + and country code.
- Paste your own samples into the preloaded tester and watch the fifteen-digit ceiling and the no-leading-zero rule do their work.
E.164 is the wire format of telephony: a plus sign, a country code that never opens with zero, fifteen digits at most. This pattern gates exactly that and nothing more — no parentheses, no dashes, no national quirks. Normalize first, match second, and hand regional questions to libphonenumber. All ten vectors re-execute on every build.
Examples
^\+?[1-9]\d{1,14}$pattern /^\+?[1-9]\d{1,14}$/
+14155552671 ✓ matches
+49301234567 ✓ matches
(415) 555-2671 ✗ no match
+8612345678901234 ✗ no matchBoth refusals are deliberate: national formatting belongs to a formatter, and sixteen digits exceed what E.164 allots to any number on the planet.
^\+[1-9]\d{1,14}$pragmatic /^\+?[1-9]\d{1,14}$/
strict /^\+[1-9]\d{1,14}$/
14155552671 pragmatic ✓ matches strict ✗ no match
+14155552671 pragmatic ✓ matches strict ✓ matches
555-2671 pragmatic ✗ no match strict ✗ no matchOne optional character separates the variants: bare national digits clear the pragmatic gate and stop at strict, which demands the international prefix.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
A digit gate is not a phone validator
Whether a matching string is dialable in your country, which lengths a region permits, how extensions attach — none of that is regex territory. Google's libphonenumber ships the per-region metadata; treat this pattern as the cheap fence in front of it.
Common errors
Invalid regular expression: /^\(\d{3}) \d{3}-\d{4}$/: Unmatched ')'- The escaped \( opens a literal parenthesis, but the bare ) still closes a group that was never opened. Escape both halves — though matching formatted numbers is usually the wrong goal; strip formatting instead.
FAQ
Why does 0044 20 7946 0958 fail when it dials fine?
Trunk prefixes and spaces are national dialling conventions, not E.164. Rewrite it as +442079460958 — drop the 00 and the separators, keep the country code — and both variants accept it.
Should numbers be stored with or without the +?
Store the strict form with its + — unambiguous across borders and clean to sort. Accept the prefix-less shape at intake, normalize once, keep one spelling everywhere.
Can one regex validate numbers for a specific country?
Not honestly — allowed lengths and prefixes vary by region and change over time. Gate the E.164 shape here, then let libphonenumber judge regional validity with maintained metadata.