kumar
kumar

Reputation: 21

Regex to exclude same-digit delimited phone numbers excludes all phone numbers

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

Answers (3)

1.618
1.618

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

robinCTS
robinCTS

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

Demo 🔗


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

The fourth bird
The fourth bird

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

  • From the beginning of the string ^
  • Match the first digit in a capturing group (\d)
  • A negative lookahead which asserts that what follows is not the same digit 9 times (?!\1{9})
  • A negative lookahead which asserts that what follows is not the pattern with hypens (?!\1{2}-\1{3}-\1{4})
  • Match the digits with or without a hyphen by using a backreference to the second group \d{2}(-?)\d{3}\2\d{4}
  • The end of the string $

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

Related Questions