I would also suggest looking at the "libphonenumber" Google Library. I know it is not regex but it does exactly what you want.
For example, it will recognize that:
15555555555
is a possible number but not a valid number. It also supports countries outside the US.
Highlights of functionality:
- Parsing/formatting/validating phone numbers for all countries/regions of the world.
getNumberType
- gets the type of the number based on the number itself; able to distinguish Fixed-line, Mobile, Toll-free, Premium Rate, Shared Cost, VoIP and Personal Numbers (whenever feasible).
isNumberMatch
- gets a confidence level on whether two numbers could be the same.
getExampleNumber
/getExampleNumberByType
- provides valid example numbers for all countries/regions, with the option of specifying which type of example phone number is needed.
isPossibleNumber
- quickly guessing whether a number is a possible phonenumber by using only the length information, much faster than a full validation.
isValidNumber
- full validation of a phone number for a region using length and prefix information.
AsYouTypeFormatter
- formats phone numbers on-the-fly when users enter each digit.
findNumbers
- finds numbers in text input.
PhoneNumberOfflineGeocoder
- provides geographical information related to a phone number.
Examples
The biggest problem with phone number validation is it is very culturally dependant.
- America
(408) 974–2042
is a valid US number
(999) 974–2042
is not a valid US number
- Australia
0404 999 999
is a valid Australian number
(02) 9999 9999
is also a valid Australian number
(09) 9999 9999
is not a valid Australian number
A regular expression is fine for checking the format of a phone number, but it's not really going to be able to check the validity of a phone number.
I would suggest skipping a simple regular expression to test your phone number against, and using a library such as Google's libphonenumber
(link to GitHub project).
Introducing libphonenumber!
Using one of your more complex examples, 1-234-567-8901 x1234
, you get the following data out of libphonenumber
(link to online demo):
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results:
E164 format +12345678901
Original format (234) 567-8901 ext. 123
National format (234) 567-8901 ext. 123
International format +1 234-567-8901 ext. 123
Out-of-country format from US 1 (234) 567-8901 ext. 123
Out-of-country format from CH 00 1 234-567-8901 ext. 123
So not only do you learn if the phone number is valid (which it is), but you also get consistent phone number formatting in your locale.
As a bonus, libphonenumber
has a number of datasets to check the validity of phone numbers, as well, so checking a number such as +61299999999
(the international version of (02) 9999 9999
) returns as a valid number with formatting:
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() true
Formatting Results
E164 format +61299999999
Original format 61 2 9999 9999
National format (02) 9999 9999
International format +61 2 9999 9999
Out-of-country format from US 011 61 2 9999 9999
Out-of-country format from CH 00 61 2 9999 9999
libphonenumber also gives you many additional benefits, such as grabbing the location that the phone number is detected as being, and also getting the time zone information from the phone number:
PhoneNumberOfflineGeocoder Results
Location Australia
PhoneNumberToTimeZonesMapper Results
Time zone(s) [Australia/Sydney]
But the invalid Australian phone number ((09) 9999 9999
) returns that it is not a valid phone number.
Validation Results
Result from isPossibleNumber() true
Result from isValidNumber() false
Google's version has code for Java and Javascript, but people have also implemented libraries for other languages that use the Google i18n phone number dataset:
Unless you are certain that you are always going to be accepting numbers from one locale, and they are always going to be in one format, I would heavily suggest not writing your own code for this, and using libphonenumber for validating and displaying phone numbers.
True
if a phone number is valid, but you really just wanted a correct phone number. For anyone who is trying to sanitize phone numbers typed by end-users into a webpage or cellphone app, I recommend simply have 4 or 5 lines of code which goes left to right one character at a time and discards all non-numbers.(303)873-9919
becomes3038739919
. After deleting all non-numbers you can insert (dots.
), insert (hyphens-
) or slashes at the proper positions.