0

I am having trouble finding a pattern that would detect the following

909-999-9999

909 999 9999

(909) 999-9999

(909) 999 9999

999 999 9999

9999999999

\A[(]?[0-9]{3}[)]?[ ,-][0-9]{3}[ ,-][0-9]{3}\z

I tried it but it doesn't work for all the instances . I was thinking I can divide the problem by putting each character into an array and then checking it. but then the code would be too long.

miken32
  • 42,008
  • 16
  • 111
  • 154
Shivam Gupta
  • 77
  • 1
  • 8
  • `"\A[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}\z"` should work. you just didnt have the `?` operator for some of your groups, as well as the final repeat number should be 4, not 3 – R Nar Oct 15 '15 at 21:28
  • Did any of the solutions below help in the end? Do you need more assistance? – Wiktor Stribiżew Dec 22 '21 at 11:28

2 Answers2

3

You have 4 digits in the last group, and you specify 3 in the regex.

You also need to apply a ? quantifier (1 or 0 occurrence) to the separators since they are optional.

Use

^[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}$

See the demo here

PHP demo:

$re = "/\A[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}\z/"; 
$strs = array("909-999-9999", "909 999 9999", "(909) 999-9999", "(909) 999 9999", "999 999 9999","9999999999"); 
$vals = preg_grep($re, $strs);
print_r($vals);

And another one:

$re = "/\A[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}\z/"; 
$str = "909-999-9999";
if (preg_match($re, $str, $m)) {
    echo "MATCHED!";
}

BTW, optional ? subpatterns perform better than alternations.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

Try this regex:

^(?:\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4}$

Explaining:

^                 # from start
(?:               # one of
    \(\d{3}\)     # '(999)' sequence
        |         # OR
    \d{3}         # '999' sequence
)                 #
[- ]?             # may exist space or hyphen
\d{3}             # three digits
[- ]?             # may exist space or hyphen
\d{4}             # four digits
$                 # end of string

Hope it helps.