Reputation: 2815
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.
Upvotes: 1060
Views: 1219369
Reputation: 515
As another post advises, it is best to use libphonenumber and/or possibly other well-maintained libraries for this, rather than a regular expression. I want to mention two other useful resources.
Aside from (1) google-libphonenumber, (2) International Telephone Input is a good frontend library (GitHub links). intl-tel-input also has a nice searchable drop-down feature with flags, and many useful functions - for instance allowing precise or imprecise validation (the latter being less susceptible to changed formatting rules), and for formatting the number.
Also, it makes sense to validate the number both front-end so as not to forward invalid numbers in vain, and back-end so as not to store invalid numbers.
To that end, if you are using Node back-end, (3) PhoneValidator.JS is a wrapper of the two aforementioned libraries that lets you implement phone number validation with just a couple of lines front-end and back-end, and also includes a green-valid/red-invalid toggle of the field background - while retaining the nice design of intl-tel-input and the power of google-libphonenumber.
If you only want the backend part, you can of course use only that, still with just two lines of code, and possibly combine it with the React component that intl-tel-input provides here.
If you have very specific needs PhoneValidator.JS may not be for you, but otherwise it is a fast and easy way to get frontend and backend validation implemented. And of course, customizations can still be done by looking at the google-libphonenumber (link to Node version) and intl-tel-input documentation.
Front-end
const htmlIds = { formId: 'formId', inputFieldId: 'inputId' };
let phoneValidator = new PhoneValidatorFE(htmlIds); // an 'options' argument optional
The instantiation also adds the hidden fields countryCode
and domesticPortion
to the form. Before submitting the form or calling your API you may validate the number via:
if(phoneValidator.validNumber()) {
Back-end
The backend validation-method takes an object as an argument with the two same properties that were sent via hidden fields from the frontend:
let number = { countryCode: req.body.countryCode, domesticPortion: req.body.domesticPortion };
if(PhoneValidator.isPhoneNumber(number)) {
If valid, the number
object now contains for instance:
{
countryCode: '46',
regionCode: 'SE',
countryName: 'Sweden',
domesticPortion: ’9 99 99 99’,
full: {
international: '+46 9 99 99 99’,
domestic: '09-99 99 99’
}
};
Upvotes: 0
Reputation: 600
I believe this is the one You'll need to detect phone numbers, you also should use a line of programming just to ensure a valid number.
((\+ ?)?(\(\d{1,5}\)[ \-.]?)?\d+([ \-.]?\d+)*)
The 1st capturing group is the number.
This will check
Once you get the number, to verify it's best to check their length (min 4 yes 4 digits exist, max 15) Python example:
def validate_number(number:str):
n = sum([1 if c.isdigit() else 0 for c in number ])
return n >= 4 and n <= 15
JS example
function validate_number(number){
n = 0
for(i=0;i<number.length;i++){
// check if the character is a number
if(/^\d+$/.test(number.charAt(i))){
n += 1
}
}
return (n>=4 && n<=15)
}
Upvotes: 0
Reputation: 3520
I chose below regExp but when I copy and paste phone numbers it didn't work
/^(\+?\d{0,4})?[ -]?(\(?\d{3}\)?)[ -]?(\(?\d{3}\)?)[ -]?(\(?\d{4}\)?)?$/
The reason is there was a different dash symbol(this ‑
not -
). So I modified regExp again by adding it too.
/^(\+?\d{0,4})?[ -‑]?(\(?\d{3}\)?)[ -‑]?(\(?\d{3}\)?)[ -‑]?(\(?\d{4}\)?)?$/
Upvotes: 0
Reputation: 1890
This is a simple Regular Expression pattern for Philippine Mobile Phone Numbers:
((\+[0-9]{2})|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}
or
((\+63)|0)[.\- ]?9[0-9]{2}[.\- ]?[0-9]{3}[.\- ]?[0-9]{4}
will match these:
+63.917.123.4567
+63-917-123-4567
+63 917 123 4567
+639171234567
09171234567
The first one will match ANY two digit country code, while the second one will match the Philippine country code exclusively.
Upvotes: 11
Reputation: 4241
/^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d*)\)?)[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?)+)(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$/i
This matches:
- (+351) 282 43 50 50
- 90191919908
- 555-8909
- 001 6867684
- 001 6867684x1
- 1 (234) 567-8901
- 1-234-567-8901 x1234
- 1-234-567-8901 ext1234
- 1-234 567.89/01 ext.1234
- 1(234)5678901x1234
- (123)8575973
- (0055)(123)8575973
- +1 282 282 2828
On $n, it saves:
You can test it on https://regex101.com/r/kFzb1s/42
Upvotes: 95
Reputation: 126
Simple regex and other tricks works.
.*
but showing an Hint / Example / Placeholder / Tooltip for the input.
Then verifying on the frontend before submitting that the format is actually correct is a best experience out there.
This would simplify formats for an inexperienced user.
Upvotes: -3
Reputation: 245
Although it's not regex, you can use the function validate_phone()
from the Python library DataPrep to validate US phone numbers. Install it with pip install dataprep
.
>>> from dataprep.clean import validate_phone
>>> df = pd.DataFrame({'phone': ['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, '12345678', '123-456-78987']})
>>> validate_phone(df['phone'])
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 False
8 False
Name: phone, dtype: bool
Upvotes: 0
Reputation: 854
Java generates REGEX for valid phone numbers
Another alternative is to let Java generate a REGEX that macthes all variations of phone numbers read from a list. This means that the list called validPhoneNumbersFormat, seen below in code context, is deciding which phone number format is valid.
Note: This type of algorithm would work for any language handling regular expressions.
Code snippet that generates the REGEX:
Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
.map(s -> s.replaceAll("\\+", "\\\\+"))
.map(s -> s.replaceAll("\\d", "\\\\d"))
.map(s -> s.replaceAll("\\.", "\\\\."))
.map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
.collect(Collectors.toSet());
String regex = String.join("|", regexSet);
Code snippet in context:
public class TestBench {
public static void main(String[] args) {
List<String> validPhoneNumbersFormat = Arrays.asList(
"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",
"+12345678901",
"(234) 567-8901 ext. 123",
"+1 234-567-8901 ext. 123",
"1 (234) 567-8901 ext. 123",
"00 1 234-567-8901 ext. 123",
"+210-998-234-01234",
"210-998-234-01234",
"+21099823401234",
"+210-(998)-(234)-(01234)",
"(+351) 282 43 50 50",
"90191919908",
"555-8909",
"001 6867684",
"001 6867684x1",
"1 (234) 567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1-234 567.89/01 ext.1234",
"1(234)5678901x1234",
"(123)8575973",
"(0055)(123)8575973"
);
Set<String> uniqueValidPhoneNumbersFormats = new LinkedHashSet<>(validPhoneNumbersFormat);
List<String> invalidPhoneNumbers = Arrays.asList(
"+210-99A-234-01234", // FAIL
"+210-999-234-0\"\"234", // FAIL
"+210-999-234-02;4", // FAIL
"-210+998-234-01234", // FAIL
"+210-998)-(234-(01234" // FAIL
);
List<String> invalidAndValidPhoneNumbers = new ArrayList<>();
invalidAndValidPhoneNumbers.addAll(invalidPhoneNumbers);
invalidAndValidPhoneNumbers.addAll(uniqueValidPhoneNumbersFormats);
Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
.map(s -> s.replaceAll("\\+", "\\\\+"))
.map(s -> s.replaceAll("\\d", "\\\\d"))
.map(s -> s.replaceAll("\\.", "\\\\."))
.map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
.collect(Collectors.toSet());
String regex = String.join("|", regexSet);
List<String> result = new ArrayList<>();
Pattern pattern = Pattern.compile(regex);
for (String phoneNumber : invalidAndValidPhoneNumbers) {
Matcher matcher = pattern.matcher(phoneNumber);
if(matcher.matches()) {
result.add(matcher.group());
}
}
// Output:
if(uniqueValidPhoneNumbersFormats.size() == result.size()) {
System.out.println("All valid numbers was matched!\n");
}
result.forEach(System.out::println);
}
}
Output:
All valid numbers was matched!
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
...
...
...
Upvotes: 0
Reputation: 8539
since there are so many options to write a phone number, one can just test that are enough digits in it, no matter how they are separated. i found 9 to 14 digits work for me:
^\D*(\d\D*){9,14}$
true:
false:
if you do want to support those last two examples - just remove the upper limit:
(\d\D*){9,}
(the ^$
are not needed if there's no upper limit)
Upvotes: -1
Reputation: 66112
If at all possible, I would recommend to have four separate fields—Area Code, 3-digit prefix, 4 digit part, extension—so that the user 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.
Upvotes: -1
Reputation: 7537
I answered this question on another SO question before deciding to also include my answer as an answer on this thread, because no one was addressing how to require/not require items, just handing out regexs: Regex working wrong, matching unexpected things
From my post on that site, I've created a quick guide to assist anyone with making their own regex for their own desired phone number format, which I will caveat (like I did on the other site) that if you are too restrictive, you may not get the desired results, and there is no "one size fits all" solution to accepting all possible phone numbers in the world - only what you decide to accept as your format of choice. Use at your own risk.
/^
[\s]
or \s
[(]
and [)]
. Using \(
and \)
is ugly and can make things confusing.?
after it-
or [-]
. If you do not put it first or last in a series of other characters, though, you may need to escape it: \-
[-.\s]
will require a hyphen, period, or space. A question mark after the last bracket will make all of those optional for that slot.\d{3}
: Requires a 3-digit number: 000-999. Shorthand for
[0-9][0-9][0-9]
.[2-9]
: Requires a digit 2-9 for that slot.(\+|1\s)?
: Accept a "plus" or a 1 and a space (pipe character, |
, is "or"), and make it optional. The "plus" sign must be escaped.[246]
will require a 2, 4, or 6. (?:77|78)
or [77|78]
will require 77 or 78.$/
: End the expressionUpvotes: 58
Reputation: 419
.*
If the users want to give you their phone numbers, then trust them to get it right. If they do not want to give it to you then forcing them to enter a valid number will either send them to a competitor's site or make them enter a random string that fits your regex. I might even be tempted to look up the number of a premium rate horoscope hotline 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"
Upvotes: 337
Reputation: 8103
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:
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. The biggest problem with phone number validation is it is very culturally dependant.
(408) 974–2042
is a valid US number(999) 974–2042
is not a valid US number0404 999 999
is a valid Australian number(02) 9999 9999
is also a valid Australian number(09) 9999 9999
is not a valid Australian numberA 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).
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.
Upvotes: 204
Reputation: 22440
As there is no language tag with this post, I'm gonna give a regex
solution used within python.
The expression itself:
1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+
When used within python:
import re
phonelist ="1-234-567-8901,1-234-567-8901 1234,1-234-567-8901 1234,1 (234) 567-8901,1.234.567.8901,1/234/567/8901,12345678901"
phonenumber = '\n'.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)])
print(phonenumber)
Output:
1-234-567-8901
1-234-567-8901 1234
1-234-567-8901 1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
Upvotes: 1
Reputation: 21531
Try this (It is for Indian mobile number validation):
if (!phoneNumber.matches("^[6-9]\\d{9}$")) {
return false;
} else {
return true;
}
Upvotes: 0
Reputation: 204
Note It takes as an input a US mobile number in any format and optionally accepts a second parameter - set true if you want the output mobile number formatted to look pretty. If the number provided is not a mobile number, it simple returns false. If a mobile number IS detected, it returns the entire sanitized number instead of true.
function isValidMobile(num,format) {
if (!format) format=false
var m1 = /^(\W|^)[(]{0,1}\d{3}[)]{0,1}[.]{0,1}[\s-]{0,1}\d{3}[\s-]{0,1}[\s.]{0,1}\d{4}(\W|$)/
if(!m1.test(num)) {
return false
}
num = num.replace(/ /g,'').replace(/\./g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'').replace(/\[/g,'').replace(/\]/g,'').replace(/\+/g,'').replace(/\~/g,'').replace(/\{/g,'').replace(/\*/g,'').replace(/\}/g,'')
if ((num.length < 10) || (num.length > 11) || (num.substring(0,1)=='0') || (num.substring(1,1)=='0') || ((num.length==10)&&(num.substring(0,1)=='1'))||((num.length==11)&&(num.substring(0,1)!='1'))) return false;
num = (num.length == 11) ? num : ('1' + num);
if ((num.length == 11) && (num.substring(0,1) == "1")) {
if (format===true) {
return '(' + num.substr(1,3) + ') ' + num.substr(4,3) + '-' + num.substr(7,4)
} else {
return num
}
} else {
return false;
}
}
Upvotes: 0
Reputation: 11896
Find String regex = "^\\+(?:[0-9] ?){6,14}[0-9]$";
helpful for international numbers.
Upvotes: 2
Reputation: 63580
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
+441234567890
Then when you display, reformat to your hearts content. e.g.
1 (234) 567-8901
1 (234) 567-8901 x1234
Upvotes: 554
Reputation: 624
It's near to impossible to handle all sorts of international phone numbers using simple regex.
You'd be better off using a service like numverify.com, they're offering a free JSON API for international phone number validation, plus you'll get some useful details on country, location, carrier and line type with every request.
Upvotes: 1
Reputation: 51
I found this to work quite well:
^\(*\+*[1-9]{0,3}\)*-*[1-9]{0,3}[-. /]*\(*[2-9]\d{2}\)*[-. /]*\d{3}[-. /]*\d{4} *e*x*t*\.* *\d{0,4}$
It works for these number formats:
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
1-234-567-8901 ext. 1234
(+351) 282 433 5050
Make sure to use global AND multiline flags to make sure.
Link: http://www.regexr.com/3bp4b
Upvotes: 14
Reputation: 1418
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
Upvotes: 23
Reputation: 6155
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
Upvotes: 34
Reputation: 1618
For anyone interested in doing something similar with Irish mobile phone numbers, here's a straightforward way of accomplishing it:
PHP
<?php
$pattern = "/^(083|086|085|086|087)\d{7}$/";
$phone = "087343266";
if (preg_match($pattern,$phone)) echo "Match";
else echo "Not match";
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();
});
});
Upvotes: 2
Reputation: 7541
My attempt at an unrestrictive regex:
/^[+#*\(\)\[\]]*([0-9][ ext+-pw#*\(\)\[\]]*){6,45}$/
Accepts:
+(01) 123 (456) 789 ext555
123456
*44 123-456-789 [321]
123456
123456789012345678901234567890123456789012345
*****++[](][((( 123456tteexxttppww
Rejects:
mob 07777 777777
1234 567 890 after 5pm
john smith
(empty)
1234567890123456789012345678901234567890123456
911
It is up to you to sanitize it for display. After validating it could be a number though.
Upvotes: 15
Reputation: 17671
Here's a wonderful pattern that most closely matched the validation that I needed to achieve. I'm not the original author, but I think it's well worth sharing as I found this problem to be very complex and without a concise or widely useful answer.
The following regex will catch widely used number and character combinations in a variety of global phone number formats:
/^\s*(?:\+?(\d{1,3}))?([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/gm
Positive:
+42 555.123.4567
+1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926) 1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292
Negative:
926 3 4
8 800 600-APPLE
Original source: http://www.regexr.com/38pvb
Upvotes: 19
Reputation: 155
After reading through these answers, it looks like there wasn't a straightforward regular expression that can parse through a bunch of text and pull out phone numbers in any format (including international with and without the plus sign).
Here's what I used for a client project recently, where we had to convert all phone numbers in any format to tel: links.
So far, it's been working with everything they've thrown at it, but if errors come up, I'll update this answer.
Regex:
/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/
PHP function to replace all phone numbers with tel: links (in case anyone is curious):
function phoneToTel($number) {
$return = preg_replace('/(\+*\d{1,})*([ |\(])*(\d{3})[^\d]*(\d{3})[^\d]*(\d{4})/', '<a href="tel:$1$3$4$5">$1 ($3) $4-$5</a>', $number); // includes international
return $return;
}
Upvotes: 8
Reputation: 5728
Working example for Turkey, just change the
d{9}
according to your needs and start using it.
function validateMobile($phone)
{
$pattern = "/^(05)\d{9}$/";
if (!preg_match($pattern, $phone))
{
return false;
}
return true;
}
$phone = "0532486061";
if(!validateMobile($phone))
{
echo 'Incorrect Mobile Number!';
}
$phone = "05324860614";
if(validateMobile($phone))
{
echo 'Correct Mobile Number!';
}
Upvotes: 1
Reputation:
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
Upvotes: 3
Reputation: 61
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.
Upvotes: 11