Reputation: 21
I've been working with a regex expression:
/^(\d)(?!\1{2}\1{3}\1{4}$)\d{2}\d{3}\d{4}$/
which excludes a 10-digit phone number with all digits the same, for example, 2222222222
or 3333333333
.
Now, I need the regex to exclude same-digit phone numbers formatted like 222-222-2222
or 333-333-3333
.
This is the modified regex I tried in order to allow for the delimiters:
/^\((\d)(?!\1{2}-\1{3}-\1{4}$)\d{2}\)\d{3}-\d{4}$/
Unfortunately, it excludes all phone numbers. Where have I gone wrong?
Upvotes: 1
Views: 300
Reputation: 1765
Try this:
/^(?:(?:(\d)(?!\1)){3}-?){2}(?:(?:(\d)(?!\1)){4})$/
I prefer regexr.com for testing.
Explaination:
(?:(?:(\d)(?!\1)){3}-?)
A group of 3 digits, but only if they're not repeats. A single '-' at the end is optional.
The above two patterns must match twice. The last pattern is the same except it matches 4 digits, and doesn't allow for a '-' at the end.
Edited to fix the 11 and 12 digit matching problem.
Upvotes: 0
Reputation: 5886
You were very close with your delimiter version. Roughly speaking*, you were just missing a )
in your lookahead and the first -
in the actual match. (As an aside, the first $
is also redundant.)
Assuming you wish to allow both 123-456-7890
and (123)-456-7890
, the working* regex is:
Regex 1
^\(?(\d)(?!\1{2}\)?-\1{3}-\1{4})\d{2}\)?-\d{3}-\d{4}$
| |_| ||_
| | | |
| missed (optional) ')' | missed '-'
| |
'?' required to make '(' and ')' optional
If you wish to allow 1234567890
and (123)4567890
as well, you need to make the hyphens optional. Note that in the actual match, you have to "link" the two hypens by using a capturing group and back reference, otherwise 123-4567890
, 123456-7890
, etc, will also be matched:
Regex 2
^\(?(\d)(?!\1{2}\)?-?\1{3}-?\1{4})\d{2}\)?(-)?\d{3}\2\d{4}$
| | |__| ||
optional hypens | back reference to captured hypen
|
optional captured hypen
*Caveat:
Both (123-456-7890
& 123)-456-7890
(and (1234567890
& 123)4567890
for the second regex) are allowed. If you wish to exclude these, the positive lookahead, (?=\(\d{3}\)|\d{3}[^)])
, is required at the start of the regexes:
Regex 1a
^(?=\(\d{3}\)|\d{3}[^)])\(?(\d)(?!\1{2}\)?-\1{3}-\1{4})\d{2}\)?-\d{3}-\d{4}$
|_____________________||_________________________________________________|
| |
positive lookahead Regex 1
Regex 2a
^(?=\(\d{3}\)|\d{3}[^)])\(?(\d)(?!\1{2}\)?-?\1{3}-?\1{4})\d{2}\)?(-)?\d{3}\2\d{4}$
|_____________________||_______________________________________________________|
| |
positive lookahead Regex 2
positive lookahead
^(?=\(\d{3}\)|\d{3}[^)])
|_______| |_______|
| |
| or starts with 3 digits, then no ")"
|
Either starts with "(", then 3 digits, then ")"
Upvotes: 0
Reputation: 163362
To match a 10 digit phone number phonenumber but exclude when they are all the same digits like 2222222222
or 222-222-2222
you might change you regex to:
^(\d)(?!\1{9})(?!\1{2}-\1{3}-\1{4})\d{2}(-?)\d{3}\2\d{4}$
Explanation
^
(\d)
(?!\1{9})
(?!\1{2}-\1{3}-\1{4})
\d{2}(-?)\d{3}\2\d{4}
$
If you would like to also accept a format like (123)-456-7890 you could for example use:
^(?!(\d)\(\1{3}\))(?!(\d)\2{9})(?!(\d)\3{2}-\3{3}-\3{4})(?:\(\d{3}\)|\d{3})(-?)?\d{3}\4\d{4}$
Upvotes: 0