Why Phone Number Regex is Harder Than Email Regex
Phone number formats are wildly inconsistent across countries, carriers, and user habits. A US number might appear as 5551234567, (555) 123-4567, 555-123-4567, +1-555-123-4567, or +1 (555) 123.4567. All of these represent the same number. Unlike email, where the @ symbol provides a reliable structural anchor, phone numbers have no universal marker — you are primarily counting digits.
This is why most senior developers recommend normalising the input first (stripping all non-digit characters) and then applying a digit-count check, rather than trying to write one mega-regex that handles every formatting variant.
Pattern Reference by Country
United States & Canada (NANP)
// Flexible — handles most common formats including optional country code
const US_PHONE = /^\+?1?[-. ]?\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
// Strict E.164 US format
const US_E164 = /^\+1[2-9]\d{2}[2-9]\d{6}$/;
// Note: area codes starting with 1 or 0 are invalid in NANP
// After stripping non-digits and optional leading 1:
const US_DIGITS = /^[2-9]\d{9}$/;India
// 10-digit mobile starting with 6–9 (Airtel, Jio, Vi, BSNL)
const IN_MOBILE = /^[6-9]\d{9}$/;
// With optional +91 or 0 prefix
const IN_FULL = /^(?:\+91|91|0)?[6-9]\d{9}$/;
// Matches: 9876543210, +919876543210, 09876543210
// Rejects: 1234567890 (starts with 1), 98765432 (too short)United Kingdom
// UK mobile (07xxx)
const UK_MOBILE = /^(?:\+44|0)7\d{9}$/;
// UK landline (01xxx, 02xxx, 03xxx)
const UK_LANDLINE = /^(?:\+44|0)[123]\d{9}$/;
// Combined UK (landline + mobile)
const UK_ANY = /^(?:\+44|0)[0-9]\d{9}$/;International E.164 (Recommended for global apps)
// Strict E.164: + followed by 8–15 digits
const E164 = /^\+[1-9]\d{7,14}$/;
// Permissive international (allows optional +, 7–15 digits)
const INTL = /^\+?[1-9]\d{6,14}$/;
// The E.164 standard (ITU-T Rec. E.164) defines a maximum of 15 digits
// including the country code. Country codes are 1–3 digits, so subscriber
// numbers can be 12–14 digits maximum.Normalisation First — The Right Approach
Rather than a single complex regex, a two-step approach is more maintainable:
function normalizeAndValidate(phone, countryCode = 'US') {
// Step 1: strip everything except digits and leading +
const stripped = phone.replace(/[^\d+]/g, '');
// Step 2: apply country-specific digit-count rules
if (countryCode === 'US') {
const digits = stripped.replace(/^\+1/, '').replace(/^1/, '');
return /^[2-9]\d{9}$/.test(digits);
}
if (countryCode === 'IN') {
const digits = stripped.replace(/^(?:\+91|91)/, '');
return /^[6-9]\d{9}$/.test(digits);
}
// Fallback: E.164 check
return /^\+[1-9]\d{7,14}$/.test(stripped);
}Testing Your Phone Regex
Open the Regex Tester and run these test cases for the US flexible pattern:
- ✅
5551234567 - ✅
(555) 123-4567 - ✅
+1-555-123-4567 - ✅
555.123.4567 - ❌
555-CALL-NOW(letters — adjust if you want to allow word substitution) - ❌
12345(too short) - ❌
+44 7700 900123(UK — should fail US pattern)