229

I found this code in some website, and it works perfectly. It validates that the phone number is in one of these formats:
(123) 456-7890 or 123-456-7890

The problem is that my client (I don't know why, maybe client stuffs) wants to add another format, the ten numbers consecutively, something like this: 1234567890.

I'm using this regular expression,

/^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/

How can I add that it also validates the another format? I'm not good with regular expressions.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Castro Roy
  • 7,623
  • 13
  • 63
  • 97
  • 3
    possible duplicate of [A comprehensive regex for phone number validation](http://stackoverflow.com/questions/123559/a-comprehensive-regex-for-phone-number-validation) – Alex Wayne Dec 02 '10 at 18:11
  • 7
    As a rule of thumb — trying to validate phone numbers is doomed to failure. What with different structures in different countries and extensions, its a very difficult problem. – Quentin Dec 02 '10 at 18:11
  • 3
    And what about e.g. the French notation? "12 34 56 78 90" Simply remove everything except numbers (except maybe a plus sign at the beginning) and check the length. – thejh Dec 02 '10 at 18:35
  • You *shouldn't*, in fact, use regular expressions to [validate phone numbers properly](http://stackoverflow.com/a/4338544/1269037). – Dan Dascalescu Feb 26 '14 at 07:52

30 Answers30

247

My regex of choice is:

/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im

Valid formats:

(123) 456-7890
(123)456-7890
123-456-7890
123.456.7890
1234567890
+31636363634
075-63546725

marty
  • 486
  • 5
  • 18
EeeeeK
  • 2,579
  • 1
  • 11
  • 2
155

First off, your format validator is obviously only appropriate for NANP (country code +1) numbers. Will your application be used by someone with a phone number from outside North America? If so, you don't want to prevent those people from entering a perfectly valid [international] number.

Secondly, your validation is incorrect. NANP numbers take the form NXX NXX XXXX where N is a digit 2-9 and X is a digit 0-9. Additionally, area codes and exchanges may not take the form N11 (end with two ones) to avoid confusion with special services except numbers in a non-geographic area code (800, 888, 877, 866, 855, 900) may have a N11 exchange.

So, your regex will pass the number (123) 123 4566 even though that is not a valid phone number. You can fix that by replacing \d{3} with [2-9]{1}\d{2}.

Finally, I get the feeling you're validating user input in a web browser. Remember that client-side validation is only a convenience you provide to the user; you still need to validate all input (again) on the server.

TL;DR don't use a regular expression to validate complex real-world data like phone numbers or URLs. Use a specialized library.

Community
  • 1
  • 1
josh3736
  • 139,160
  • 33
  • 216
  • 263
  • I agree that regex is not sufficient to validate phone numbers because the phone numbering plan actually works based on range, e.g. 12300000 to 12399999 (http://www.numberingplans.com/?page=plans&sub=phonenr&alpha_2_input=US&current_page=15242) –  Aug 27 '14 at 12:14
  • The problem is that it takes >500Kb to bundle libphonenumber in your frontend app. (https://bundlephobia.com/package/google-libphonenumber@3.2.22) I think it's a good starting point if you want to jump in phone number validation: https://github.com/google/libphonenumber/blob/master/FALSEHOODS.md Given the complexity I would also consider to use specialized online services, eg: https://validatephonenumber.com/ – dsdenes Aug 20 '21 at 09:31
80

If you are looking for 10 and only 10 digits, ignore everything but the digits-

   return value.match(/\d/g).length===10;
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • This is what I was going to suggest. Easy breezy. And too much validation can be a bad thing anyway. – mwilcox Dec 02 '10 at 22:25
  • 1
    This is the best way to go. Unless you REALLY care what format it is in, all this does is make sure the number is partially valid, and not a bunch of jibberish. – mdance Nov 29 '12 at 23:14
  • 10
    You mean match(/\d/g) not match(/\d/) or the length will be 1, not 10; also, the match on an empty string is null. At the very least it should be var m = value.match(/\d/g); return m && m.length === 10 – Doug Sep 22 '14 at 07:08
  • Or `return (value.match(/\d/g) || []).length == 10` or the much simpler (but equally flawed): `return value.replace(/\D/g,'').length == 10`. – RobG Aug 23 '16 at 05:56
  • I like this one: `/\D/gi.test(value)`. Everything that's not a digit, including whitespaces, dashes, etc... – Gus Jul 04 '19 at 01:59
51
/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]*$/g

(123) 456-7890
+(123) 456-7890
+(123)-456-7890
+(123) - 456-7890
+(123) - 456-78-90
123-456-7890
123.456.7890
1234567890
+31636363634
075-63546725

This is a very loose option and I prefer to keep it this way, mostly I use it in registration forms where the users need to add their phone number. Usually users have trouble with forms that enforce strict formatting rules, I prefer user to fill in the number and the format it in the display or before saving it to the database. http://regexr.com/3c53v

elishas
  • 621
  • 5
  • 4
  • 7
    regex slightly modified to allow e.g. for `+41 (79) 123 45 67` (Switzerland): `/^[+]?[\s./0-9]*[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/g` – Remigius Stalder Jul 26 '18 at 11:05
  • This one seems to be a good fit for me since it's not too string and seems to cover all of the international formats (and thanks @RemigiusStalder for the Switzerland fix) – Gavin Aug 31 '18 at 12:26
  • If you have a java backend, you can add phone number normalization, e.g. from https://github.com/google/libphonenumber – Remigius Stalder Oct 24 '19 at 16:02
  • 2
    Would be better to add character limit. Change the last * (asterisk) with [8, 14]: `/^[+]*[(]{0,1}[0-9]{1,3}[)]{0,1}[-\s\./0-9]{8,14}$/g` – kuzey beytar Jan 31 '21 at 09:23
36

What I would do is ignore the format and validate the numeric content:

var originalPhoneNumber = "415-555-1212";

function isValid(p) {
  var phoneRe = /^[2-9]\d{2}[2-9]\d{2}\d{4}$/;
  var digits = p.replace(/\D/g, "");
  return phoneRe.test(digits);
}
Community
  • 1
  • 1
Paul Schreiber
  • 12,531
  • 4
  • 41
  • 63
  • 1
    Agree regarding ignoring formatting, .e.g. it's very common for mobile numbers to be presented with spaces like XXXX XXX XXX but for forms to require input without spaces, i.e. as XXXXXXXXXX. – RobG Jan 05 '18 at 06:28
33

The following REGEX will validate any of these formats:

(123) 456-7890
123-456-7890
123.456.7890
1234567890

/^[(]{0,1}[0-9]{3}[)]{0,1}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/
Billbad
  • 17,651
  • 2
  • 21
  • 17
  • 3
    You need to escape the `.` or else it will match an arbitrary character, breaking your regex. – Christoph Mar 12 '13 at 10:25
  • 2
    This led me in the right direction. Thanks! Unfortunately this expression will also match (1234567890 and 123)4567890. ^((\([0-9]{3}\))|([0-9]{3}))[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4}$ takes care of that little problem. – Joe Hawkins Jun 26 '15 at 20:52
24

Where str could be any of these formarts: 555-555-5555 (555)555-5555 (555) 555-5555 555 555 5555 5555555555 1 555 555 5555

function telephoneCheck(str) {
  var isphone = /^(1\s|1|)?((\(\d{3}\))|\d{3})(\-|\s)?(\d{3})(\-|\s)?(\d{4})$/.test(str);
  alert(isphone);
}
telephoneCheck("1 555 555 5555");
Frawel
  • 3,574
  • 1
  • 17
  • 13
20

I would suggest using something clearer (especially thinking to who will have to maintain the code)... what about:

var formats = "(999)999-9999|999-999-9999|9999999999";
var r = RegExp("^(" +
               formats
                 .replace(/([\(\)])/g, "\\$1")
                 .replace(/9/g,"\\d") +
               ")$");

where the regexp is built from a clear template ? Adding a new one would then be a no-brainer and may be even the customer itself could be able to do that in a "options" page.

6502
  • 112,025
  • 15
  • 165
  • 265
11

Try this one - it includes validation for international formats too.

/^[+]?(1\-|1\s|1|\d{3}\-|\d{3}\s|)?((\(\d{3}\))|\d{3})(\-|\s)?(\d{3})(\-|\s)?(\d{4})$/g

This regex validates the following format:

  • (541) 754-3010 Domestic
  • +1-541-754-3010 International
  • 1-541-754-3010 Dialed in the US
  • 001-541-754-3010 Dialed from Germany
  • 191 541 754 3010 Dialed from France
roelofs
  • 2,132
  • 20
  • 25
harinimurugan
  • 113
  • 2
  • 8
9

Regex

Use the following Regex pattern:

/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im

Like this: <input pattern="/^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im">*


Valid formats:

(123) 456-7890,
(123)456-7890,
123-456-7890,
123.456.7890,
1234567890,
+31636363634 or
075-63546725


Tiago Rangel
  • 1,159
  • 15
  • 29
8

This will work:

/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4}$/

The ? character signifies that the preceding group should be matched zero or one times. The group (-|\s) will match either a - or a | character. Adding ? after the second occurrence of this group in your regex allows you to match a sequence of 10 consecutive digits.

Donut
  • 110,061
  • 20
  • 134
  • 146
8

try this

/^(\+{0,})(\d{0,})([(]{1}\d{1,3}[)]{0,}){0,}(\s?\d+|\+\d{2,3}\s{1}\d+|\d+){1}[\s|-]?\d+([\s|-]?\d+){1,2}(\s){0,}$/gm

valid formats

  • (123) 456-7890
  • (123)456-7890
  • 123-456-7890
  • 1234567890
  • +31636363634
  • +3(123) 123-12-12
  • +3(123)123-12-12
  • +3(123)1231212
  • +3(123) 12312123
  • +3(123) 123 12 12
  • 075-63546725
  • +7910 120 54 54
  • 910 120 54 54
  • 8 999 999 99 99

https://regex101.com/r/QXAhGV/1

7

An actually simple way:

"9001234567".match(/^\d{10}$/g)
Tiago Rangel
  • 1,159
  • 15
  • 29
Nikita Shahov
  • 281
  • 2
  • 11
6

/^\+?1?\s*?\(?\d{3}(?:\)|[-|\s])?\s*?\d{3}[-|\s]?\d{4}$/

Although this post is an old but want to leave my contribuition. these are accepted: 5555555555 555-555-5555 (555)555-5555 1(555)555-5555 1 555 555 5555 1 555-555-5555 1 (555) 555-5555

these are not accepted:

555-5555 -> to accept this use: ^\+?1?\s*?\(?(\d{3})?(?:\)|[-|\s])?\s*?\d{3}[-|\s]?\d{4}$

5555555 -> to accept this use: ^\+?1?\s*?\(?(\d{3})?(?:\)|[-|\s])?\s*?\d{3}[-|\s]?\d{4}$

1 555)555-5555 123**&!!asdf# 55555555 (6505552368) 2 (757) 622-7382 0 (757) 622-7382 -1 (757) 622-7382 2 757 622-7382 10 (757) 622-7382 27576227382 (275)76227382 2(757)6227382 2(757)622-7382 (555)5(55?)-5555

this is the code I used:

function telephoneCheck(str) {
  var patt = new RegExp(/^\+?1?\s*?\(?\d{3}(?:\)|[-|\s])?\s*?\d{3}[-|\s]?\d{4}$/);
  return patt.test(str);
}

telephoneCheck("+1 555-555-5555");
Alexey Nikonov
  • 4,958
  • 5
  • 39
  • 66
  • the only problem of this regex is that it considers valid a phone string with only one ')' or only one '(' (like "(555-555-5555") – happyZZR1400 Feb 17 '20 at 21:25
3

This reg ex is suitable for international phone numbers and multiple formats of mobile cell numbers.

Here is the regular expression: /^(+{1}\d{2,3}\s?[(]{1}\d{1,3}[)]{1}\s?\d+|+\d{2,3}\s{1}\d+|\d+){1}[\s|-]?\d+([\s|-]?\d+){1,2}$/

Here is the JavaScript function

function isValidPhone(phoneNumber) {
    var found = phoneNumber.search(/^(\+{1}\d{2,3}\s?[(]{1}\d{1,3}[)]{1}\s?\d+|\+\d{2,3}\s{1}\d+|\d+){1}[\s|-]?\d+([\s|-]?\d+){1,2}$/);
    if(found > -1) {
        return true;
    }
    else {
        return false;
    }
}

This validates the following formats:

+44 07988-825 465 (with any combination of hyphens in place of space except that only a space must follow the +44)

+44 (0) 7988-825 465 (with any combination of hyphens in place of spaces except that no hyphen can exist directly before or after the (0) and the space before or after the (0) need not exist)

123 456-789 0123 (with any combination of hyphens in place of the spaces)

123-123 123 (with any combination of hyphens in place of the spaces)

123 123456 (Space can be replaced with a hyphen)

1234567890

No double spaces or double hyphens can exist for all formats.

user2288580
  • 2,210
  • 23
  • 16
2

Everyone's answers are great, but here's one I think is a bit more comprehensive...

This is written for javascript match use of a single number in a single line:

^(?!.*911.*\d{4})((\+?1[\/ ]?)?(?![\(\. -]?555.*)\( ?[2-9][0-9]{2} ?\) ?|(\+?1[\.\/ -])?[2-9][0-9]{2}[\.\/ -]?)(?!555.?01..)([2-9][0-9]{2})[\.\/ -]?([0-9]{4})$

If you want to match at word boundaries, just change the ^ and $ to \b

I welcome any suggestions, corrections, or criticisms of this solution. As far as I can tell, this matches the NANP format (for USA numbers - I didn't validate other North American countries when creating this), avoids any 911 errors (can't be in the area code or region code), eliminates only those 555 numbers which are actually invalid (region code of 555 followed by 01xx where x = any number).

Erasmus
  • 199
  • 1
  • 3
2

This function worked for us well:

let isPhoneNumber = input => {

  try {
    let ISD_CODES = [93, 355, 213, 1684, 376, 244, 1264, 672, 1268, 54, 374, 297, 61, 43, 994, 1242, 973, 880, 1246, 375, 32, 501, 229, 1441, 975, 591, 387, 267, 55, 246, 1284, 673, 359, 226, 257, 855, 237, 1, 238, 1345, 236, 235, 56, 86, 61, 61, 57, 269, 682, 506, 385, 53, 599, 357, 420, 243, 45, 253, 1767, 1809, 1829, 1849, 670, 593, 20, 503, 240, 291, 372, 251, 500, 298, 679, 358, 33, 689, 241, 220, 995, 49, 233, 350, 30, 299, 1473, 1671, 502, 441481, 224, 245, 592, 509, 504, 852, 36, 354, 91, 62, 98, 964, 353, 441624, 972, 39, 225, 1876, 81, 441534, 962, 7, 254, 686, 383, 965, 996, 856, 371, 961, 266, 231, 218, 423, 370, 352, 853, 389, 261, 265, 60, 960, 223, 356, 692, 222, 230, 262, 52, 691, 373, 377, 976, 382, 1664, 212, 258, 95, 264, 674, 977, 31, 599, 687, 64, 505, 227, 234, 683, 850, 1670, 47, 968, 92, 680, 970, 507, 675, 595, 51, 63, 64, 48, 351, 1787, 1939, 974, 242, 262, 40, 7, 250, 590, 290, 1869, 1758, 590, 508, 1784, 685, 378, 239, 966, 221, 381, 248, 232, 65, 1721, 421, 386, 677, 252, 27, 82, 211, 34, 94, 249, 597, 47, 268, 46, 41, 963, 886, 992, 255, 66, 228, 690, 676, 1868, 216, 90, 993, 1649, 688, 1340, 256, 380, 971, 44, 1, 598, 998, 678, 379, 58, 84, 681, 212, 967, 260, 263],
      //extract numbers from string
      thenum = input.match(/[0-9]+/g).join(""),
      totalnums = thenum.length,
      last10Digits = parseInt(thenum) % 10000000000,
      ISDcode = thenum.substring(0, totalnums - 10);

    //phone numbers are generally of 8 to 16 digits
    if (totalnums >= 8 && totalnums <= 16) {
      if (ISDcode) {
        if (ISD_CODES.includes(parseInt(ISDcode))) {
          return true;
        } else {
          return false;
        }
      } else {
        return true;
      }
    }
  } catch (e) {}

  return false;
}

console.log(isPhoneNumber('91-9883208806'));
Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
2

Validate phone number + return formatted data

function validTel(str){
  str = str.replace(/[^0-9]/g, '');
  var l = str.length;
  if(l<10) return ['error', 'Tel number length < 10'];
  
  var tel = '', num = str.substr(-7),
      code = str.substr(-10, 3),
      coCode = '';
  if(l>10) {
    coCode = '+' + str.substr(0, (l-10) );
  }
  tel = coCode +' ('+ code +') '+ num;
  
  return ['succes', tel];
}

console.log(validTel('+1 [223] 123.45.67'));
VVV
  • 31
  • 2
2

I took the one provided by @marty and modified it a little bit to accommodate more cases:

/^[\+]?([0-9][\s]?|[0-9]?)([(][0-9]{3}[)][\s]?|[0-9]{3}[-\s\.]?)[0-9]{3}[-\s\.]?[0-9]{4,6}$/im

Valid formats:

  1. +1 123 4567890
  2. +11234567890
  3. +1(123)4567890
  4. +1(123)456-7890
  5. +1 (123) 456-7890
  6. +1 (123)456 7890
  7. +1 123 456-7890
  8. +1 123 456 7890
  9. +1 123-456-7890
  10. 123-456-7890
  11. 123 456-7890
  12. 123 456 7890
  13. 123 4567890
  14. 1234567890
Sergii Sopin
  • 411
  • 2
  • 11
2

Try this regular expression

/[^0-9+() -.]/g

Usage Example:

<input type="tel" id="txtUserMobile" onkeyup="this.value=this.value.replace(/[^0-9+() -.]/g,'')">

Enjoy

Adnan Zaheer
  • 392
  • 3
  • 13
1

/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4}$/

The ? character signifies that the preceding group should be matched zero or one times. The group (-|\s) will match either a - or a | character.

Ren
  • 1,111
  • 5
  • 15
  • 24
parijat
  • 11
  • 1
1

I have to agree that validating phone numbers is a difficult task. As for this specific problem i would change the regex from

/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)\d{4}$/

to

/^(()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4}$/

as the only one more element that becomes unnecessary is the last dash/space.

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • I'm really trying to up my Regex game! I'm checking your suggestion using "The Regex Coach." I'm using the regex (()?\d{3}())?(-|\s)?\d{3}(-|\s)?\d{4} and the target string (123) 456-7890 but for some reason it's only grabbing the last 7 digits. Any ideas? – Aaron Hathaway Dec 02 '10 at 18:17
  • Yep regex are a little rough on the brains... and patience. Ok try /^[(]?(\d{3})[)]?[-|\s]?(\d{3})[-|\s]?(\d{4})$/ the first part of the older regex didn't do well: "(()?\d{3}())" (() the middle parenthesis was actually seen as part of the regex syntax and not characters to be looked for. – Luc Veronneau Dec 02 '10 at 18:27
1

If you using on input tag than this code will help you. I write this code by myself and I think this is very good way to use in input. but you can change it using your format. It will help user to correct their format on input tag.

$("#phone").on('input', function() {  //this is use for every time input change.
        var inputValue = getInputValue(); //get value from input and make it usefull number
        var length = inputValue.length; //get lenth of input

        if (inputValue < 1000)
        {
            inputValue = '1('+inputValue;
        }else if (inputValue < 1000000) 
        {
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, length);
        }else if (inputValue < 10000000000) 
        {
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, 6) + '-' + inputValue.substring(6, length);
        }else
        {
            inputValue = '1('+ inputValue.substring(0, 3) + ')' + inputValue.substring(3, 6) + '-' + inputValue.substring(6, 10);
        }       
        $("#phone").val(inputValue); //correct value entered to your input.
        inputValue = getInputValue();//get value again, becuase it changed, this one using for changing color of input border
       if ((inputValue > 2000000000) && (inputValue < 9999999999))
      {
          $("#phone").css("border","black solid 1px");//if it is valid phone number than border will be black.
      }else
      {
          $("#phone").css("border","red solid 1px");//if it is invalid phone number than border will be red.
      }
  });

    function getInputValue() {
         var inputValue = $("#phone").val().replace(/\D/g,'');  //remove all non numeric character
        if (inputValue.charAt(0) == 1) // if first character is 1 than remove it.
        {
            var inputValue = inputValue.substring(1, inputValue.length);
        }
        return inputValue;
}
1

Just wanted to add a solution specifically for selecting non-local phone numbers(800 and 900 types).

(\+?1[-.(\s]?|\()?(900|8(0|4|5|6|7|8)\3+)[)\s]?[-.\s]?\d{3}[-.\s]?\d{4}
Mike T
  • 513
  • 5
  • 14
1

Try this js function. Returns true if it matches and false if it fails Ref

function ValidatePhoneNumber(phone) {
        return /^\+?([0-9]{2})\)?[-. ]?([0-9]{4})[-. ]?([0-9]{4})$/.test(phone);
}
bjoxiah
  • 11
  • 2
0

Simple Regular expression: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g

Check out the format, hope it works :
444-555-1234
f:246.555.8888
m:1235554567

Rodrigo Leite
  • 596
  • 5
  • 22
sahed moral
  • 345
  • 3
  • 13
  • Please format your answer (use four spaces as indents for a code block). An explanation to your code will also increase its quality. – Nander Speerstra Apr 04 '17 at 13:28
0
\\(?\d{3}\\)?([\-\s\.])?\d{3}\1?\d{4}

This will validate any phone number of variable format:

\\(?\d{3}\\)? finds 3 digits enclosed by parenthesis or not.

([\-\s\.])? finds any of these separator characters or not

\d{3} finds 3 digits

\1 uses the first matched separator - this ensures that the separators are the same. So (000) 999-5555 will not validate here because there is a space and dash separator, so just remove the "\1" and replace with the separator sub-pattern (doing so will also validate non standard formats). You should however be format hinting for user input anyway.

\d{4} finds 4 digits

Validates:

  • (000) 999 5555
  • (000)-999-5555
  • (000).999.5555
  • (000) 999-5555
  • (000)9995555
  • 000 999 5555
  • 000-999-5555
  • 000.999.5555
  • 0009995555

BTW this is for JavaScript hence to double escapes.

Dacmeaux
  • 9
  • 1
0

try this

/^[\+]?\d{2,}?[(]?\d{2,}[)]?[-\s\.]?\d{2,}?[-\s\.]?\d{2,}[-\s\.]?\d{0,9}$/im

valid formats:

  1. (123) 456-7890
  2. (123)456-7890
  3. 123-456-7890
  4. 123.456.7890
  5. 1234567890
  6. +31636363634
  7. +3(123) 123-12-12
  8. +3(123)123-12-12
  9. +3(123)1231212
  10. +3(123) 12312123
  11. 075-63546725
Maxym
  • 11
  • 1
  • Please make sure to include explanations with your answer. Although it may work, it is important to explain how and why in order to have complete and relevant information. Thanks for answering :) – Magix Mar 29 '19 at 21:08
0

A RegExp to Argentina´s numbers: /^((+[0-9]{1,3}))?(([0-9]{8,13})|([0-9]{3,6})-([0-9]{4,7}))$/

Valids:

X: from 8 to 13 numbers
  • XXXXXXXX
  • separate numbers by a hyphen = X from 3 to 6; Y: from 4 to 7
  • XXXX-YYYY
  • Z: from 1 to 3
  • (+Z)XXXXXXXX
  • if you use Z then (+ ) is mandatory.
    -2

    Just ignore everything but digits.

    Here is what I use:

    // USA phones should contain at least 10 digits. Most EU country codes have only 9 digits, without leading 0 and country code prefix, eg [+380] 88 888-88-88.
    // UPD. India: +91(+10 digits), China: +86(+ 10 OR 11 digits), etc.
    
    stringProto.isValidPhone = function(minDigitsCount, maxDigitsCount) { // please customize minDigitsCount!
        var str = this.trim();
        if (str) {
            var len,
                isPlus = ("+" === str[0]),
                defMin = isPlus ? 11 : 10, // 10 digits is standard w/o country code for the US, Canada and many other countries. (...and 10-digits number is DEFAULT! AK: DON'T CHANGE IT HERE!)
                                        // however, for countries like Ukraine all numbers without country code have only 9 digits length, or even 7, without regional code.
                                        // So please customize minDigitsCount accordingly to the length of numbers in your default country!
    
                defMax = isPlus ? 14 : 11; // 11 digits maximum w/o country code (China) or 14 with country code (Austria).
    
            if ((str = str.match(/\d/g)) && (str = str.join(""))) { // all digits only!
                len = str.length;
    
                return len >= (minDigitsCount || defMin) &&
                       len <= (maxDigitsCount || defMax);
            }
        }
    }