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;
}
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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With