Вы можете сделать это с помощью одного регулярного выражения:
(?!(\d)\1{2}\D?\1{3}\D?\1{4})\d{3}([-. ]?)\d{3}\2\d{4}
В качестве кода Java ваш метод будет:
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}");
}
Объяснение
Регулярное выражение состоит из 2 частей:
(?!xxx)yyy
yyy
часть:
\d{3}([-. ]?)\d{3}\2\d{4}
Что означает:
\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
Это означает, что оно будет соответствовать, например, 123-456-7890
или 123.456.7890
, но не 123.456-7890
(?!xxx)
part является отрицательным прогнозом нулевой ширины, то есть он совпадает, если выражение xxx
не совпадает, а часть xxx
имеет вид:
(\d)\1{2}\D?\1{3}\D?\1{4}
Что означает:
(\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
Поскольку вторая часть уже проверила разделители, отрицательный прогноз - просто использование более расслабленного \D
для пропуска любого символа разделителя.