I’m trying to make a regex that will only accept phone numbers in the listed formats. However if I end the first three-digit group with a closing parentheses without an opening one at the start, the test will come back true when I want it to return false. What can I do?
1 555-555-5555
1 (555) 555-5555
1(555)555-5555
1 555 555 5555
5555555555
555-555-5555
(555)555-5555
const validNumbers = /^[1]? ?[(]?[0-9]{3}[)]?s?[0-9]{3}[-s]?[0-9]{4}$/i
console.log(validNumbers.test("1 305) 9759003"))
2
Answers
In the pattern
[(]?[0-9]{3}[)]?
, the opening and closing brackets are optional. There is no relationship between those to optional brackets. So, it will match012
,(012
,012)
and(012)
.Regex cannot "remember" whether it found a bracket before or not. So, if you only want to match a closing bracket when you got an opening one, you have to explicitly distinguish between the following two patterns:
[(][0-9]{3}[)]
), or[0-9]{3}
).This translates to the following regex:
([(][0-9]{3}[)]|[0-9]{3})
. The complete regex then looks as follows:For your test string, we get the following:
Explaination:
^1? ?
: The beginning of the string may include a 1 followed by an optional space.(([0-9]{3})|[0-9]{3})
: Matches 3 digits, which may either be enclosed in matching parentheses or stand alone without them.[-s]?
: Allows an optional dash (-) or space.[0-9]{3}
: Matches the next set of 3 digits.[-s]?
: Allows another optional dash or space.[0-9]{4}$
: Matches the final set of 4 digits at the end of the string.