2

I want to validate a 10 digit USA style phone number using a Regular Expression in Javascript and then submit it to the PHP server via the url. It will be a simple text box in a form for typing in the number and a button to submit.

For example, after validation, the url might be:

thisdomainname.com/resultspage.php?phonenumber=4392931234

I know how regular expressions work but am confused by more complex ones. I have searched stackoverflow and the internet for a solution and found several but none that fits what I need exactly and/or works when I run it.

I need it to omit all non numeric characters (such as parens, dashes and periods), and also omit the extra leading "1" that is optional in USA 10 digit phone numbers.

It should allow (validate as correct) the following formats:

  • 1-(805) xxx-xxxx

  • 215.xxx.xxxx

But reject as invalid:

  • 805 931 42
  • 805 931 42ab
  • 105 931 4288

Ideally it would allow phone numbers according to the "North American Numbering Plan," which has the following rules:

"Area codes start with a number from 2–9, followed by 0–8, and then any third digit. The second group of three digits, known as the central office or exchange code, starts with a number from 2–9, followed by any two digits. The final four digits, known as the station code, have no restrictions."

I found a regex to implement this below, but I can't get it to work with the optional leading "1" digit.

^\(?([2-9][0-8][0-9])\)?[-. ]?([2-9][0-9]{2})[-. ]?([0-9]{4})$

Like I say, I have found many solutions addressing this problem in general, but none that will work with all the situations I've outlined above.

Thanks in advance.

Itay
  • 16,601
  • 2
  • 51
  • 72
Tom Panek
  • 105
  • 1
  • 7
  • 2
    You haven't asked a question. And now it looks like: "I have found some broken code over the internet and looking someone to fix it for me". Stackoverflows is primarily a community for developers, not for searching volunteers to do your job. – zerkms Sep 08 '13 at 01:48
  • You might be disappointed to know that your regexp is not perfect, even if you consider not adding the leading `1`, because it would also accept numbers like `815)-432-1234` (one parenthesis) and 815432-1234 (among other examples) – Nasser Al-Shawwa Sep 08 '13 at 01:54
  • check http://stackoverflow.com/questions/3357675/validating-us-phone-number-with-php-regex – internals-in Sep 08 '13 at 02:27

2 Answers2

3

A simpler approach is just to remove all non-digit characters and make sure the number of digits is valid

function isValidPhoneNumber(value) {
    if (!value) return false;
    var count = value.replace(/[^0-9]/g, "").length;

    return count == 10 || count == 11;
}
Robert Byrne
  • 562
  • 2
  • 13
  • Yes I agree that is much simpler, easier to understand, and probably covers over 80% of all numbers. I was just hoping for something that was more thorough. – Tom Panek Sep 08 '13 at 05:12
  • 1
    Yes I sometimes feel that way myself, but ultimately a phone number is n digits (when entered into a keypad) and there nothing more frustrating for a user than having their number rejected because the developer didn't anticipate that pattern – Robert Byrne Sep 08 '13 at 14:43
0

Agreeing w/ Robert Byrne on just stripping all non numeric characters from the input string before testing. Going further here to test the additional rules you stated regarding acceptable digits:

<?php

$testStr = "134dusrtu56sdjhsdf7890asd     01";  // input string
$parsedResult = preg_replace( '/[^\d]/', '', $testStr ); // remove non-numeric characters
$confirmation = ( preg_match( '/^[1]?[2-9][0-8][0-9][2-9][\d]{6}$/', $parsedResult ) === 1 ); // parsed numeric string meets your rules?

echo $parsedResult . ": " . (int) $confirmation; // 13456789001: 1 (1=true;0=false)

Also, just a precautionary note: never convert phone numbers to integer - overflow will likely occur. Also, it's perfectly fine to store the parsed number rather than the client's original input, especially if you use the number with automated text or dialing services.

bob-the-destroyer
  • 3,164
  • 2
  • 23
  • 30