A comprehensive regex for phone number validation
A comprehensive regex for phone number validation
I'm trying to put together a comprehensive regex to validate phone numbers. Ideally it would handle international formats, but it must handle US formats, including the following:
- 1-234-567-8901
- 1-234-567-8901 x1234
- 1-234-567-8901 ext1234
- 1 (234) 567-8901
- 1.234.567.8901
- 1/234/567/8901
- 12345678901
I'll answer with my current attempt, but I'm hoping somebody has something better and/or more elegant.
Answer by Nicholas Trandem for A comprehensive regex for phone number validation
Here's my best try so far. It handles the formats above but I'm sure I'm missing some other possible formats.
^\d?(?:(?:[\+]?(?:[\d]{1,3}(?:[ ]+|[\-.])))?[(]?(?:[\d]{3})[\-/)]?(?:[ ]+)?)?(?:[a-zA-Z2-9][a-zA-Z0-9 \-.]{6,})(?:(?:[ ]+|[xX]|(i:ext[\.]?)){1,2}(?:[\d]{1,5}))?$
Answer by Rob Wells for A comprehensive regex for phone number validation
Have you had a look over at RegExLib?
Entering US phone number brought back quite a list of possibilities.
Answer by Justin R. for A comprehensive regex for phone number validation
It turns out that there's something of a spec for this, at least for North America, called the NANP.
You need to specify exactly what you want. What are legal delimiters? Spaces, dashes, and periods? No delimiter allowed? Can one mix delimiters (e.g., +0.111-222.3333)? How are extensions (e.g., 111-222-3333 x 44444) going to be handled? What about special numbers, like 911? Is the area code going to be optional or required?
Here's a regex for a 7 or 10 digit number, with extensions allowed, delimiters are spaces, dashes, or periods:
^(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?$
Answer by scunliffe for A comprehensive regex for phone number validation
Better option... just strip all non-digit characters on input (except 'x' and leading '+' signs), taking care because of the British tendency to write numbers in the non-standard form +44 (0) ...
when asked to use the international prefix (in that specific case, you should discard the (0)
entirely).
Then, you end up with values like:
12345678901 12345678901x1234 345678901x1234 12344678901 12345678901 12345678901 12345678901 +4112345678 +44123456789
Then when you display, reformat to your hearts content. e.g.
1 (234) 567-8901 1 (234) 567-8901 x1234
Answer by Joe Philllips for A comprehensive regex for phone number validation
I work for a market research company and we have to filter these types of input alllll the time. You're complicating it too much. Just strip the non-alphanumeric chars, and see if there's an extension.
For further analysis you can subscribe to one of many providers that will give you access to a database of valid numbers as well as tell you if they're landlines or mobiles, disconnected, etc. It costs money.
Answer by Kibbee for A comprehensive regex for phone number validation
Is it possible to have the for display 4 separate fields ( Area Code, 3-digit prefix, 4 digit part, extension) so that they can input each part of the address separately, and you can verify each piece individually? That way you can not only make verification much easier, you can store your phone numbers in a more consistent format in the database.
Answer by Adam Davis for A comprehensive regex for phone number validation
You'll have a hard time dealing with international numbers with a single/simple regex, see this post on the difficulties of international (and even north american) phone numbers.
You'll want to parse the first few digits to determine what the country code is, then act differently based on the country.
Beyond that - the list you gave does not include another common US format - leaving off the initial 1. Most cell phones in the US don't require it, and it'll start to baffle the younger generation unless they've dialed internationally.
You've correctly identified that it's a tricky problem...
Answer by Jon Ericson for A comprehensive regex for phone number validation
I believe the Number::Phone::US and Regexp::Common (particularly the source of Regexp::Common::URI::RFC2806) Perl modules could help.
The question should probably be specified in a bit more detail to explain the purpose of validating the numbers. For instance, 911 is a valid number in the US, but 911x isn't for any value of x. That's so that the phone company can calculate when you are done dialing. There are several variations on this issue. But your regex doesn't check the area code portion, so that doesn't seem to be a concern.
Like validating email addresses, even if you have a valid result you can't know if it's assigned to someone until you try it.
If you are trying to validate user input, why not normalize the result and be done with it? If the user puts in a number you can't recognize as a valid number, either save it as inputted or strip out undailable characters. The Number::Phone::Normalize Perl module could be a source of inspiration.
Answer by indiv for A comprehensive regex for phone number validation
Although the answer to strip all whitespace is neat, it doesn't really solve the problem that's posed, which is to find a regex. Take, for instance, my test script that downloads a web page and extracts all phone numbers using the regex. Since you'd need a regex anyway, you might as well have the regex do all the work. I came up with this:
1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?
Here's a perl script to test it. When you match, $1 contains the area code, $2 and $3 contain the phone number, and $5 contains the extension. My test script downloads a file from the internet and prints all the phone numbers in it.
#!/usr/bin/perl my $us_phone_regex = '1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?'; my @tests = ( "1-234-567-8901", "1-234-567-8901 x1234", "1-234-567-8901 ext1234", "1 (234) 567-8901", "1.234.567.8901", "1/234/567/8901", "12345678901", "not a phone number" ); foreach my $num (@tests) { if( $num =~ m/$us_phone_regex/ ) { print "match [$1-$2-$3]\n" if not defined $4; print "match [$1-$2-$3 $5]\n" if defined $4; } else { print "no match [$num]\n"; } } # # Extract all phone numbers from an arbitrary file. # my $external_filename = 'http://web.textfiles.com/ezines/PHREAKSANDGEEKS/PnG-spring05.txt'; my @external_file = `curl $external_filename`; foreach my $line (@external_file) { if( $line =~ m/$us_phone_regex/ ) { print "match $1 $2 $3\n"; } }
Edit:
You can change \W* to \s*\W?\s* in the regex to tighten it up a bit. I wasn't thinking of the regex in terms of, say, validating user input on a form when I wrote it, but this change makes it possible to use the regex for that purpose.
'1?\s*\W?\s*([2-9][0-8][0-9])\s*\W?\s*([2-9][0-9]{2})\s*\W?\s*([0-9]{4})(\se?x?t?(\d*))?';
Answer by piCookie for A comprehensive regex for phone number validation
My inclination is to agree that stripping non-digits and just accepting what's there is best. Maybe to ensure at least a couple digits are present, although that does prohibit something like an alphabetic phone number "ASK-JAKE" for example.
A couple simple perl expressions might be:
@f = /(\d+)/g; tr/0-9//dc;
Use the first one to keep the digit groups together, which may give formatting clues. Use the second one to trivially toss all non-digits.
Is it a worry that there may need to be a pause and then more keys entered? Or something like 555-1212 (wait for the beep) 123?
Answer by ron0 for A comprehensive regex for phone number validation
If you're talking about form validation, the regexp to validate correct meaning as well as correct data is going to be extremely complex because of varying country and provider standards. It will also be hard to keep up to date.
I interpret the question as looking for a broadly valid pattern, which may not be internally consistent - for example having a valid set of numbers, but not validating that the trunk-line, exchange, etc. to the valid pattern for the country code prefix.
North America is straightforward, and for international I prefer to use an 'idiomatic' pattern which covers the ways in which people specify and remember their numbers:
^((((\(\d{3}\))|(\d{3}-))\d{3}-\d{4})|(\+?\d{2}((-| )\d{1,8}){1,5}))(( x| ext)\d{1,5}){0,1}$
The North American pattern makes sure that if one parenthesis is included both are. The international accounts for an optional initial '+' and country code. After that, you're in the idiom. Valid matches would be:
(xxx)xxx-xxxx
(xxx)-xxx-xxxx
(xxx)xxx-xxxx x123
12 1234 123 1 x1111
12 12 12 12 12
12 1 1234 123456 x12345
+12 1234 1234
+12 12 12 1234
+12 1234 5678
+12 12345678
This may be biased as my experience is limited to North America, Europe and a small bit of Asia.
Answer by Keith Wiggans for A comprehensive regex for phone number validation
I was struggling with the same issue, trying to make my application future proof, but these guys got me going in the right direction. I'm not actually checking the number itself to see if it works or not, I'm just trying to make sure that a series of numbers was entered that may or may not have an extension.
Worst case scenario if the user had to pull an unformatted number from the XML file, they would still just type the numbers into the phone's numberpad 012345678x5
, no real reason to keep it pretty. That kind of RegEx would come out something like this for me:
\d+ ?\w{0,9} ?\d+
01234467 extension 123456
01234567x123456
01234567890
Answer by rooskie for A comprehensive regex for phone number validation
Do a replace on formatting characters, then check the remaining for phone validity. In PHP,
$replace = array( ' ', '-', '/', '(', ')', ',', '.' ); //etc; as needed preg_match( '/1?[0-9]{10}((ext|x)[0-9]{1,4})?/i', str_replace( $replace, '', $phone_num );
Breaking a complex regexp like this can be just as effective, but much more simple.
Answer by Dave Kirby for A comprehensive regex for phone number validation
.*
If the user wants to give you his phone number, then trust him to get it right. If he does not want to give it to you then forcing him to enter a valid number will either send him to a competitor's site or make him enter a random string that fits your regex. I might even be tempted to look up the number of a premium rate sex line and enter that instead.
I would also consider any of the following as valid entries on a web site:
"123 456 7890 until 6pm, then 098 765 4321" "123 456 7890 or try my mobile on 098 765 4321" "ex-directory - mind your own business"
Answer by Artjom Kurapov for A comprehensive regex for phone number validation
I wrote simpliest (although i didn't need dot in it).
^([0-9\(\)\/\+ \-]*)$
As mentioned below, it checks only for characters, not its structure/order
Answer by Ben Clifford for A comprehensive regex for phone number validation
Note that stripping ()
characters does not work for a style of writing UK numbers that is common: +44 (0) 1234 567890
which means dial either the international number:
+441234567890
or in the UK dial 01234567890
Answer by Chris for A comprehensive regex for phone number validation
I found this to be something interesting. I have not tested it but it looks as if it would work
"; $number = '123-555-555'; if(validate_telephone_number($number, $formats)) { echo $number.' is a valid phone number.'; } echo "
"; $number = '1800-1234-5678'; if(validate_telephone_number($number, $formats)) { echo $number.' is a valid phone number.'; } echo "
"; $number = '(800) 555-123'; if(validate_telephone_number($number, $formats)) { echo $number.' is a valid phone number.'; } echo "
"; $number = '1234567890'; if(validate_telephone_number($number, $formats)) { echo $number.' is a valid phone number.'; } ?>
Answer by Ian for A comprehensive regex for phone number validation
pattern="^[\d|\+|\(]+[\)|\d|\s|-]*[\d]$" validateat="onsubmit"
Must end with a digit, can begin with ( or + or a digit, and may contain + - ( or )
Answer by mindplay.dk for A comprehensive regex for phone number validation
My gut feeling is reinforced by the amount of replies to this topic - that there is a virtually infinite number of solutions to this problem, none of which are going to be elegant.
Honestly, I would recommend you don't try to validate phone numbers. Even if you could write a big, hairy validator that would allow all the different legitimate formats, it would end up allowing pretty much anything even remotely resembling a phone number in the first place.
In my opinion, the most elegant solution is to validate a minimum length, nothing more.
Answer by Bob-ob for A comprehensive regex for phone number validation
For anyone interested in doing something similar with Irish mobile phone numbers, here's a straightforward way of accomplishing it:
PHP
There is also a JQuery solution on that link.
EDIT:
jQuery solution:
$(function(){ //original field values var field_values = { //id : value 'url' : 'url', 'yourname' : 'yourname', 'email' : 'email', 'phone' : 'phone' }; var url =$("input#url").val(); var yourname =$("input#yourname").val(); var email =$("input#email").val(); var phone =$("input#phone").val(); //inputfocus $('input#url').inputfocus({ value: field_values['url'] }); $('input#yourname').inputfocus({ value: field_values['yourname'] }); $('input#email').inputfocus({ value: field_values['email'] }); $('input#phone').inputfocus({ value: field_values['phone'] }); //reset progress bar $('#progress').css('width','0'); $('#progress_text').html('0% Complete'); //first_step $('form').submit(function(){ return false; }); $('#submit_first').click(function(){ //remove classes $('#first_step input').removeClass('error').removeClass('valid'); //ckeck if inputs aren't empty var fields = $('#first_step input[type=text]'); var error = 0; fields.each(function(){ var value = $(this).val(); if( value.length<12 || value==field_values[$(this).attr('id')] ) { $(this).addClass('error'); $(this).effect("shake", { times:3 }, 50); error++; } else { $(this).addClass('valid'); } }); if(!error) { if( $('#password').val() != $('#cpassword').val() ) { $('#first_step input[type=password]').each(function(){ $(this).removeClass('valid').addClass('error'); $(this).effect("shake", { times:3 }, 50); }); return false; } else { //update progress bar $('#progress_text').html('33% Complete'); $('#progress').css('width','113px'); //slide steps $('#first_step').slideUp(); $('#second_step').slideDown(); } } else return false; }); //second section $('#submit_second').click(function(){ //remove classes $('#second_step input').removeClass('error').removeClass('valid'); var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; var fields = $('#second_step input[type=text]'); var error = 0; fields.each(function(){ var value = $(this).val(); if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) { $(this).addClass('error'); $(this).effect("shake", { times:3 }, 50); error++; } else { $(this).addClass('valid'); } function validatePhone(phone) { var a = document.getElementById(phone).value; var filter = /^[0-9-+]+$/; if (filter.test(a)) { return true; } else { return false; } } $('#phone').blur(function(e) { if (validatePhone('txtPhone')) { $('#spnPhoneStatus').html('Valid'); $('#spnPhoneStatus').css('color', 'green'); } else { $('#spnPhoneStatus').html('Invalid'); $('#spnPhoneStatus').css('color', 'red'); } }); }); if(!error) { //update progress bar $('#progress_text').html('66% Complete'); $('#progress').css('width','226px'); //slide steps $('#second_step').slideUp(); $('#fourth_step').slideDown(); } else return false; }); $('#submit_second').click(function(){ //update progress bar $('#progress_text').html('100% Complete'); $('#progress').css('width','339px'); //prepare the fourth step var fields = new Array( $('#url').val(), $('#yourname').val(), $('#email').val(), $('#phone').val() ); var tr = $('#fourth_step tr'); tr.each(function(){ //alert( fields[$(this).index()] ) $(this).children('td:nth-child(2)').html(fields[$(this).index()]); }); //slide steps $('#third_step').slideUp(); $('#fourth_step').slideDown(); }); $('#submit_fourth').click(function(){ url =$("input#url").val(); yourname =$("input#yourname").val(); email =$("input#email").val(); phone =$("input#phone").val(); //send information to server var dataString = 'url='+ url + '&yourname=' + yourname + '&email=' + email + '&phone=' + phone; alert (dataString);//return false; $.ajax({ type: "POST", url: "http://clients.socialnetworkingsolutions.com/infobox/contact/", data: "url="+url+"&yourname="+yourname+"&email="+email+'&phone=' + phone, cache: false, success: function(data) { console.log("form submitted"); alert("success"); } }); return false; }); //back button $('.back').click(function(){ var container = $(this).parent('div'), previous = container.prev(); switch(previous.attr('id')) { case 'first_step' : $('#progress_text').html('0% Complete'); $('#progress').css('width','0px'); break; case 'second_step': $('#progress_text').html('33% Complete'); $('#progress').css('width','113px'); break; case 'third_step' : $('#progress_text').html('66% Complete'); $('#progress').css('width','226px'); break; default: break; } $(container).slideUp(); $(previous).slideDown(); }); });
Do you have a spam issue on this blog; I also am a blogger, and I was wondering your situation; many of us have created some nice practices and we are looking to exchange strategies with others, please shoot me an e-mail if interested.
ReplyDeleteEmail Validation API to detect temp emails