Phone Number Regex Patterns by Country
Phone number formats vary wildly across countries — the US uses 10 digits grouped as (XXX) XXX-XXXX, the UK has variable-length area codes, Germany allows 10–13 digit subscriber numbers, and countries like India and Brazil have recently added digits to their mobile numbers. A single regex pattern cannot reliably validate every global phone number, but with the right set of country-specific patterns and a solid understanding of international standards, you can build validation logic that handles the vast majority of real-world inputs.
This guide provides tested, production-ready regex patterns for the most common phone number formats, explains the reasoning behind each pattern, and covers the pitfalls that cause validation failures in real applications. Every pattern has been tested against real phone number datasets — not just the happy path examples.
Test these patterns live: Open our Regex Tester and paste any pattern below to validate it against your phone numbers in real time.
Universal: E.164 International Format
The E.164 standard (defined by the ITU-T) is the safest format for storing and transmitting phone numbers globally. Every valid phone number in the world can be represented in E.164 format:
^\+[1-9]\d{6,14}$
Format: + followed by country code and subscriber number (7–15 digits total, no spaces or formatting).
Examples: +14155551234, +442071234567, +905551234567, +81312345678
Why E.164 matters
E.164 solves the ambiguity problem: 07911123456 could be a UK mobile number (if dialed from the UK) or completely invalid (if dialed internationally). By always storing the full international format, you eliminate context-dependent interpretation. Major APIs including Twilio, AWS SNS, and Google Cloud Telephony require E.164 input.
| Property | E.164 | Local Format |
|---|---|---|
| Globally unique | ✅ Yes | ❌ No — depends on dialing context |
| Machine-comparable | ✅ Yes — string equality works | ❌ No — (415) 555-1234 ≠ 415.555.1234 |
| API compatible | ✅ Twilio, AWS, Google all require it | ❌ Requires normalization first |
| Human readable | ❌ Not intuitive for users | ✅ Familiar local formatting |
Recommendation: Store in E.164, display in local format, accept flexible input from users.
United States & Canada (+1)
North America uses the NANP (North American Numbering Plan) with a consistent 10-digit format: 3-digit area code + 7-digit subscriber number.
^(\+1)?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$
Matches: (415) 555-1234, 415-555-1234, 415.555.1234, +1 415 555 1234, 4155551234
NANP edge cases to watch
- Area codes never start with 0 or 1 (e.g.,
012or115are invalid) - Exchange codes (middle 3 digits) also never start with 0 or 1
- Numbers starting with
555in the0100–0199range are reserved for fictional use
A stricter pattern that enforces these rules:
^(\+1)?[-.\s]?\(?[2-9]\d{2}\)?[-.\s]?[2-9]\d{2}[-.\s]?\d{4}$
JavaScript validation example
function validateUSPhone(input) {
const cleaned = input.replace(/[\s\-\(\)\.]/g, '');
const pattern = /^(\+?1)?[2-9]\d{2}[2-9]\d{6}$/;
if (!pattern.test(cleaned)) {
return { valid: false, error: 'Invalid US/Canada phone number' };
}
// Normalize to E.164
const digits = cleaned.replace(/\D/g, '');
const e164 = digits.length === 10 ? `+1${digits}` : `+${digits}`;
return { valid: true, e164, display: `(${digits.slice(-10, -7)}) ${digits.slice(-7, -4)}-${digits.slice(-4)}` };
}
United Kingdom (+44)
UK phone numbers have variable-length area codes (2–5 digits) and total lengths of 10 or 11 digits (excluding the leading 0 or +44). This makes UK number validation more complex than most countries.
^(\+44|0)\d{10,11}$
Matches: +447911123456, 07911123456, 02071234567
UK number types
| Type | Pattern | Example | Digits after 0/+44 |
|---|---|---|---|
| Mobile | 07xxx | 07911 123456 | 10 |
| London | 020 | 020 7123 4567 | 10 |
| Other geographic | 01xxx / 011x | 0161 234 5678 | 10 |
| Non-geographic | 03xx | 0345 123 4567 | 10 |
| Premium rate | 09xx | 0906 123 4567 | 10 |
A more precise pattern for UK mobile numbers only:
^(\+44|0)7\d{9}$
Germany (+49)
German phone numbers are notoriously variable in length — mobile numbers are typically 11 digits, but landline numbers can range from 10 to 13 digits depending on the area code.
^(\+49|0)\d{10,13}$
Matches: +4915112345678, 015112345678, +4930123456
German mobile prefixes
All German mobile numbers start with 015x, 016x, or 017x:
^(\+49|0)(1[567]\d)\d{7,8}$
France (+33)
French numbers are consistently 10 digits (including the leading 0) with mobile numbers starting with 06 or 07:
^(\+33|0)[1-9]\d{8}$
Matches: +33612345678, 0612345678, 0145678901
Turkey (+90)
Turkish numbers follow a consistent format: 10-digit subscriber number with mobile numbers starting with 5:
^(\+90|0)?\s?\(?\d{3}\)?\s?\d{3}\s?\d{2}\s?\d{2}$
Matches: +90 555 123 45 67, 0555 123 45 67, 05551234567
Turkish mobile-only pattern
^(\+90|0)?5\d{9}$
India (+91)
Indian mobile numbers are 10 digits starting with 6, 7, 8, or 9. The country recently moved from 10-digit to 10-digit mobile numbers (after adding digits in 2003):
^(\+91|0)?[6-9]\d{9}$
Matches: +919876543210, 09876543210, 9876543210
Brazil (+55)
Brazilian numbers include a 2-digit area code (DDD). Mobile numbers have 9 digits (starting with 9), while landlines have 8 digits:
^(\+55|0)?\d{2}9?\d{8}$
Matches: +5511987654321, 011987654321, 1187654321
Japan (+81)
Japanese numbers have variable-length area codes (1–5 digits). Mobile numbers start with 070, 080, or 090:
^(\+81|0)\d{9,10}$
Mobile-only:
^(\+81|0)[789]0\d{8}$
Multi-Country Validation Function
Here is a production-ready validation function that handles multiple countries:
const PHONE_PATTERNS = {
US: { pattern: /^(\+?1)?[2-9]\d{2}[2-9]\d{6}$/, code: '+1', digits: 10 },
GB: { pattern: /^(\+?44|0)\d{10,11}$/, code: '+44', digits: 10 },
DE: { pattern: /^(\+?49|0)\d{10,13}$/, code: '+49', digits: 10 },
FR: { pattern: /^(\+?33|0)[1-9]\d{8}$/, code: '+33', digits: 9 },
TR: { pattern: /^(\+?90|0)?5\d{9}$/, code: '+90', digits: 10 },
IN: { pattern: /^(\+?91|0)?[6-9]\d{9}$/, code: '+91', digits: 10 },
BR: { pattern: /^(\+?55|0)?\d{2}9?\d{8}$/, code: '+55', digits: 11 },
JP: { pattern: /^(\+?81|0)\d{9,10}$/, code: '+81', digits: 10 },
};
function validatePhone(input, countryCode = null) {
const cleaned = input.replace(/[\s\-\(\)\.]/g, '');
// If country specified, validate against that pattern
if (countryCode && PHONE_PATTERNS[countryCode]) {
const { pattern } = PHONE_PATTERNS[countryCode];
return pattern.test(cleaned);
}
// Try E.164 first
if (/^\+[1-9]\d{6,14}$/.test(cleaned)) return true;
// Try all country patterns
return Object.values(PHONE_PATTERNS).some(({ pattern }) => pattern.test(cleaned));
}
Python equivalent
import re
PHONE_PATTERNS = {
'US': r'^(\+?1)?[2-9]\d{2}[2-9]\d{6}$',
'GB': r'^(\+?44|0)\d{10,11}$',
'DE': r'^(\+?49|0)\d{10,13}$',
'FR': r'^(\+?33|0)[1-9]\d{8}$',
'TR': r'^(\+?90|0)?5\d{9}$',
'IN': r'^(\+?91|0)?[6-9]\d{9}$',
}
def validate_phone(number: str, country: str = None) -> bool:
cleaned = re.sub(r'[\s\-\(\)\.]', '', number)
if country and country in PHONE_PATTERNS:
return bool(re.match(PHONE_PATTERNS[country], cleaned))
# Try E.164
if re.match(r'^\+[1-9]\d{6,14}$', cleaned):
return True
return any(re.match(p, cleaned) for p in PHONE_PATTERNS.values())
Common Mistakes
1. Requiring exact formatting
❌ Wrong: Rejecting 4155551234 because it lacks dashes
✅ Right: Strip formatting characters before validation, then normalize to E.164
2. Hardcoding a single country format
❌ Wrong: Using \d{3}-\d{3}-\d{4} globally
✅ Right: Accept E.164 input or detect country from prefix, then apply country-specific validation
3. Using regex for complete validation
❌ Wrong: Trusting regex to confirm a number is real and reachable
✅ Right: Use regex for format validation, then verify reachability via an SMS/call API (Twilio Lookup, NumVerify)
4. Forgetting to normalize before storage
❌ Wrong: Storing (415) 555-1234 and +14155551234 as different contacts
✅ Right: Normalize to E.164 before storage — then string equality works for deduplication
5. Blocking valid numbers with overly strict patterns
❌ Wrong: Requiring exactly 10 digits for all countries
✅ Right: Research the target country’s number format. Germany allows 10–13 digits; UK has 10 or 11.
Regex vs Library: When to Use What
| Scenario | Use Regex | Use libphonenumber |
|---|---|---|
| Quick client-side format check | ✅ | ❌ Overkill (250KB+ bundle) |
| Server-side validation | 🟡 For simple cases | ✅ Always preferred |
| Determining carrier/type | ❌ Cannot do this | ✅ Built-in |
| Formatting for display | ❌ Error-prone | ✅ Locale-aware formatting |
| Detecting country from number | ❌ Complex and fragile | ✅ Built-in |
Google’s libphonenumber is the gold standard for production phone validation. Available in Java (original), JavaScript (google-libphonenumber, libphonenumber-js), Python (phonenumbers), Go (phonenumbers), and most other languages.
// Using libphonenumber-js (lightweight alternative, ~140KB)
import { parsePhoneNumber, isValidPhoneNumber } from 'libphonenumber-js';
const phone = parsePhoneNumber('+14155551234');
console.log(phone.country); // 'US'
console.log(phone.formatNational()); // '(415) 555-1234'
console.log(phone.isValid()); // true
Flexible Input Cleaner
Before validating, strip formatting characters:
const clean = phone.replace(/[\s\-\(\)\.]/g, '');
// Then validate the cleaned number
Frequently Asked Questions
What is the maximum length of a phone number?
According to the E.164 standard, the maximum length is 15 digits (including the country code). The shortest valid E.164 numbers are 7 digits. In practice, most countries use 10–12 digits total.
Should I validate phone numbers on the client or server?
Both. Use regex on the client for instant feedback (format validation), then use a library like libphonenumber on the server for definitive validation (format + plausibility). Never trust client-side validation alone.
How do I handle country code detection?
If the input starts with +, the country code is embedded. Otherwise, you need context — either ask the user to select their country, infer from their IP address / browser locale, or default to the most common country for your application.
This article is part of our Regular Expressions Guide series.