You haven't said what language you're doing this in, so we don't know what kinds of limitations are placed on your regex parser. For example, traditional sed
is limited to BRE, awk and grep can handle ERE, and grep on linux systems will handle PCRE. Perl will do PCRE also, of course, as will Python and PHP. But JavaScript only supports a subset of BRE, and misses some of the classic shortcuts for POSIX classes.
So ... to do this in BRE, which everything supports, your brackets are taken literally, and you have limited range controls:
^([[:digit:]]\{3\})[[:space:]]\{0,1\}[[:digit:]]\{3\}-[[:digit:]]\{4\}$
But this is arduous and painful. You're probably using something that at least supports ERE:
^\([[:digit:]]{3}\)[[:space:]]?[[:digit:]]{3}-[[:digit:]]{4}$
And if your parser supports class shorthand, you can shorten this further:
^\(\d{3}\)\s?\d{3}-\d{4}
This last one could be used with perl or PHP's PCRE support, but not with sed, awk or grep.
Also, I'll point out that this is not a good way to handle input validation. You want more flexibility. It would be a better idea to, for example,
- strip out all non-digit characters
- if the result is 10 digits, check for a valid area code
- if the result is 11 digits and the first digit is 1, check for a valid area code
- else, consider this an International number
You probably would need to come up with some other conditions too.