Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phone Number Validation Should Fail For All Same Number

Tags:

java

regex

I am trying to write regex where it should fail if all same numbers supplied as phone number. When I supplied with with below input it passes the validation. 999.999.9999 or 999-999-9999 or 999 999 9999. Any suggestion on regex pattern on how to fail validation it supplied all same number.

    private static boolean validatePhoneNumber(String phoneNo) {
        //validate phone numbers of format "1234567890"
        if (phoneNo.matches("\\d{10}")) return true;

        //validating phone number with -, . or spaces
        else if(phoneNo.matches("\\d{3}[-\\.\\s]\\d{3}[-\\.\\s]\\d{4}")) return true;

        //Invalid phone number where 999.999.9999 or 999-999-9999 or 999 999 9999
        else if(phoneNo.matches"(\\D?[0-9]{3}\\D?)[\\s][0-9]{3}-[0-9]{4}")) return false;

        //return false if nothing matches the input
        else return false;

    }
like image 651
Maana Avatar asked Nov 20 '25 10:11

Maana


2 Answers

You can do it with a single regex:

(?!(\d)\1{2}\D?\1{3}\D?\1{4})\d{3}([-. ]?)\d{3}\2\d{4}

As Java code, your method would be:

private static boolean validatePhoneNumber(String phoneNo) {
    // Check if phone number is valid format (optional -, . or space)
    // e.g. "1234567890", "123-456-7890", "123.456.7890", or "123 456 7890"
    // and is that all digits are not the same, e.g. "999-999-9999"
    return phoneNo.matches("(?!(\\d)\\1{2}\\D?\\1{3}\\D?\\1{4})\\d{3}([-. ]?)\\d{3}\\2\\d{4}");
}

Explanation

The regex is in 2 parts:

(?!xxx)yyy

The yyy part is:

\d{3}([-. ]?)\d{3}\2\d{4}

Which means:

\d{3}     Match 3 digits
([-. ]?)  Match a dash, dot, space, or nothing, and capture it (capture group #2)
\d{3}     Match 3 digits
\2        Match the previously captured separator
\d{4}     Match 4 digits

This means that it will match e.g. 123-456-7890 or 123.456.7890, but not 123.456-7890

The (?!xxx) part is a zero-width negative lookahead, i.e. it matches if the xxx expression doesn't match, and the xxx part is:

(\d)\1{2}\D?\1{3}\D?\1{4}

Which means:

(\d)   Match a digit and capture it (capture group #1)
\1{2}  Match 2 more of the captured digit
\D?    Optionally match a non-digit
\1{3}  Match 3 more of the captured digit
\D?    Optionally match a non-digit
\1{4}  Match 4 more of the captured digit

Since the second part has already verified the separators, the negative look-ahead is just using a more relaxed \D to skip any separator character.

like image 187
Andreas Avatar answered Nov 22 '25 00:11

Andreas


Although you can write a regex to do this it feels more readable with iteration.

boolean uniqueDigits = phoneNo.chars()
        .filter(Character::isDigit)
        .distinct()
        .count() >= 2;
like image 30
Karol Dowbecki Avatar answered Nov 22 '25 01:11

Karol Dowbecki



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!