Need help with telephone regular expression

I suck at regular expressions! I need help!

I need a regular expression that will validate a standard North American telephone number. It should accept the following formats:

(###) ###-####
###-####
### ###-####
### ### ####

Here's the catch. I'm using the regular expression to validate as the phone number is being typed so it needs to successfully validate along the way.

Can someone please help?
LVL 20
Russ SuterAsked:
Who is Participating?
 
ahoffmannConnect With a Mentor Commented:
([(]?\d{3}[)]?[ -]?\d{3}[ -]?\d{4})[^\d]?

exactly what you asked for: allowing *one* space or dash on two special positions and optional ( left oft 1st digit and ) right after 3'rd digit. () are part of the match. Only mismatch is when () are not balanced.
This regex can be used global.
0
 
ahoffmannCommented:
here is the raw regex:

[)]?\d\d\d[) -]\d\d\d(\d|[) -]\d\d\d\d)
0
 
Russ SuterAuthor Commented:
It doesn't work.
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
Lolly-InkCommented:
This example validates while being typed. Only tested in IE7.
<html>
<style>
   *
   {
      font-family: Arial, Helvetica, sans-serif;
   }
</style>
<script>
   var _keyCode = 
   {
      VK_BACK:     0x08,
      VK_TAB:      0x09,
      VK_SUBTRACT: 0x6D,
      VK_HYPHEN:   0xBD
   };
 
   function keyDownPhone(inputPhone, evt)
   {
      evt = evt ? evt : window.event;
      var r = 
      [
         /^(\((\d(\d(\d(\)( (\d(\d(\d(-(\d(\d(\d(\d)?)?)?)?)?)?)?)?)?)?)?)?)?)?$/, // (###) ###-####
         /^(\d(\d(\d(-(\d(\d(\d(\d)?)?)?)?)?)?)?)?$/, // ###-####
         /^(\d(\d(\d( (\d(\d(\d(-(\d(\d(\d(\d)?)?)?)?)?)?)?)?)?)?)?)?$/, // ### ###-####
         /^(\d(\d(\d( (\d(\d(\d( (\d(\d(\d(\d)?)?)?)?)?)?)?)?)?)?)?)?$/ // ### ### ####
      ];
      var c = String.fromCharCode(evt.keyCode);
      switch (evt.keyCode)
      {
         case _keyCode.VK_SUBTRACT:
         case _keyCode.VK_HYPHEN:
            if (!(evt.shiftKey))
            {
               c = "-";
            }
            break;
         case _keyCode.VK_BACK:
         case _keyCode.VK_TAB:
            return true;
            break;
      }
      if (evt.shiftKey)
      {
         switch (c)
         {
            case "9":
               c = "(";
               break;
            case "0":
               c = ")";
               break;
            default:
               c = "?";
               break;
         }
      }
      for (var index = 0; index < r.length; index++)
      {
         if (r[index].test(inputPhone.value + c))
         {
            return true;
         }
      }
      event.cancelBubble = true;
      event.returnValue  = false;
      if (event.preventDefault) event.preventDefault();
      if (event.stopPropagation) event.stopPropagation();
      return false;
   }
</script>
<body onload="formTest.inputPhone.focus()">
   <form name="formTest">
      Other: <input name="inputOther" type="text"/>
      Phone: <input name="inputPhone" type="text" onkeydown="keyDownPhone(this, event)"/>
      Other: <input name="inputOther" type="text"/>
   </form>
</body>
</html>

Open in new window

0
 
Hube02Commented:
You want to use a single regular expression to validate it as it is being typed?

if other words, if the user types in the number "(123) 456-7890" all of the following would validate:
(
(1
(12
(123
(123)
(123)
(123) 4
(123) 45
etc............................

What language are you running it it?
0
 
Russ SuterAuthor Commented:
Hube, you have correctly defined the problem. This is going to be done using Javascript.
0
 
Hube02Commented:
You might want to try out Lolly-Ink's solution. The regular expressions he uses look like they will work, and these can easily be added to by following those examples if you decide to allow other variations (like ###.###.### which seems popular lately)

Unfortunately, JavaScript does not support look behind, and this would be the only way to truly validate all the possibilities with a single expression that would not grow to enormous proportions.

for instance "123)" should not validate because there is a closing parenthesis without an opening parenthesis. Similarly, you would not want it to match "123-12-1". Without a look behind there is no way to tell if there is a ( and three numbers before a ) and there is no way to tell that the correct sequence exists before the second -

although, you could concatenate them all of Lolly-Ink's into a very lengthy regular expression full of OR's

^((expression1)|(expression2)|(expression3)|(etc...))$
0
 
ahoffmannCommented:
please describe more detailled what a "validate a standard North American telephone number" is for you
For example are following valid:
  xxx xxx.xxxx
  xxx xxxx.xxx
  xxxxxxxxxx
  xxx-xxxx
  xxxxxxx
  (xxx)xxxxxx
  (xxx) xxx-xxxx
and many, many more ...

If such numbers are valid, please describe exactly what is not valid.
0
 
Russ SuterAuthor Commented:
I'm mainly looking for the following 3 patterns:

(###) ###-####
### ### ####
##########

I'd like the expression to be flexible enough so that spaces and dashes are interchangeable.
0
 
Bryan ButlerCommented:
so, is this pseudo code it...

if typing a non-numeric except for '(', ')','-' or " "(space), then fail.  OR
if '(' is typed, and it isn't the first char, then fail OR
if ')' is typed, and it isn't preceded by '(###' then fail OR
if '-' is typed and it isn't preceded by ### then fail OR
if typing more than 10 digits fail
otherwise things are good to go

There are tons of "what ifs" and this is only considering the 3 cases you describe in general.  If you want the spaces to be verified in the right position, then that adds some more "ORs"; the '-' verified in the right place, then that's more; the spaces and dashes interchangeable, then that's even more ORs.  

Are you saying there can only be those three (with flexibility of spaces and dashes), or can it be:

### #######
(###)### #### (no space between R paren and 1st digit of LATA)
(###)#######

I guess there's not any others, but these minor differences may matter to you and others.  
0
 
Hans LangerCommented:
(
 (\(\d{3}\)\s\d{3}\-)   <--- for "(###) ###"
 |
 (\d{3}\s\d{3}\s) <--- for "### ### "
 |
 (\d{6}) <-- for "######"
)
\d{4}$ <-- all condition finish wit 4 digit

Reg exp:

((\(\d{3}\)\s\d{3}\-)|(\d{3}\s\d{3}\s)|(\d{6}))\d{4}$
0
 
Bryan ButlerCommented:
And another case would be:

( ### ) ### - ####

With spaces before/after the parens.  Do you need to handle this?
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.