How best to partially validate a phone number using Java

Viewed 713

I need to validate the beginning of a phone number, by this I mean I need to make sure that a country code was provided. The phone number should start with a plus sign followed by a minimum of 1 number and a maximum of 3 numbers followed by a hyphen.

Example of valid numbers...

+1-555-5555

+12-5555555

+123-(555) 555-5555

Examples of an invalid phone number

+1(555) 555-5555

5555555555

+5555555555

This is what I have so far. What I'm doing is stripping all non-digits to verify that I have a minimum of 10 numbers. I then verify that I have a country code of a minimum of 3 numbers. After that, if the phone number doesn't begin with a "+", I prepend one.

private boolean isPhoneNumberValid(String phoneNumber) {
  if (!isPhoneNumberLengthValid(phoneNumber) || !isCountryCodeLenghtValid(phoneNumber)) {
    return false;
  }

  if (!phoneNumber.startsWith("+")) {
    request.getDestination().setMobilePhoneNumber("+" + phoneNumber);
  }

  return true;
}

private boolean isPhoneNumberLengthValid(String phoneNumber) {
  return phoneNumber.replaceAll("\\D+","").length() < 10;
}

private boolean isCountryCodeLenghtValid(String phoneNumber) {
  String countryCode = StringUtils.left(phoneNumber, phoneNumber.indexOf("-")).replaceAll("\\D+","");

  return countryCode.length() >= 1 && countryCode.length() <= 3;
}

What is the best way of validating the country code?

4 Answers

First of all I have to say that it's usually a bad idea to require phone numbers to fit a specific format and length as you'll invalidate plenty of valid numbers this way, but I don't know your use case.

Despite the joke I'd use regular expressions:

\+\d{1,3}-[()\d\s-]+

This regular expressions matches strings that have

  • a literal plus,
  • followed by 1-3 digits
  • then a hyphen
  • then one or more characters in the set of brackets, digits, spaces, or hyphens

The last category could be altered to fit your exact specifications.


import java.util.regex.Pattern;  

class PhoneNumber {
  protected static void checkNumber(String number) {
    System.out.println(number + " : " + (
      Pattern.matches("\\+\\d{1,3}[-][()\\d\\s-]+", number) 
        ? "valid" : "invalid"
      )
    );
  }

  public static void main(String[] args) {
    String number;
    checkNumber("+1-555-5555");
    checkNumber("+12-5555555");
    checkNumber("+123-(555) 555-5555");
    checkNumber("+1(555) 555-5555");
    checkNumber("5555555555");
    checkNumber("+5555555555");
  }
}

This produces:

+1-555-5555 : valid
+12-5555555 : valid
+123-(555) 555-5555 : valid
+1(555) 555-5555 : invalid
5555555555 : invalid
+5555555555 : invalid

Try this.

  • starts with a +
  • then 1-3 digits.
  • then a -
  • followed by anything.
    String[] tel = { "+1-555-5555",
                "+12-5555555",
                "+123-(555) 555-5555",
                "+1- 555-5555",
                "(555)555-5555",
                "+1 (555) 555-5555",
                "+12-(555) 555-555"};

        String pat =
                "\\+\\d{1,3}-.*";
        for (String s : tel) {
           System.out.printf("%20s -> %s%n", s, s.matches(pat) ? "good" : "bad");
        }

For your example phone numbers, you might pattern with an optional group to match the digits between parenthesis and make the hyphen optional.

^\+\d{1,3}-(?:\(\d{3}\)\h*)?\d{3}-?\d{4}$

Explanation

  • ^ Start of string
  • \+\d{1,3}-
  • (?: Non capture group
    • \(\d{3}\)\h* Match (, 3 digits, ) and 0+ horizontal whitespace chars
  • )? close group and make it optional
  • \d{3}-?\d{4} Match 3 digits, an optional - and 4 digits
  • $ End of string

Regex demo | Java demo

In Java

String regex = "^\\+\\d{1,3}-(?:\\(\\d{3}\\)\\h*)?\\d{3}-?\\d{4}$";

For example

String strs[] = { 
        "+1-555-5555",
        "+12-5555555",
        "+123-(555) 555-5555",
        "+1(555) 555-5555",
        "5555555555",
        "+5555555555",
        "+123-)(----"
    };
String regex = "\\+\\d{1,3}-(?:\\(\\d{3}\\)\\h*)?\\d{3}-?\\d{4}";
for (String s : strs)
    System.out.printf("%s --> %s%n", s, s.matches(regex) ? "Match" : "No match");

Output

+1-555-5555 --> Match
+12-5555555 --> Match
+123-(555) 555-5555 --> Match
+1(555) 555-5555 --> No match
5555555555 --> No match
+5555555555 --> No match
+123-)(---- --> No match

You can use the regex mentioned in the solution given below:

public class Main {
    public static void main(String[] args) {
        String[] phoneNumbers = { "+1-555-5555", "+12-5555555", "+123-(555) 555-5555", "+1(555) 555-5555", "5555555555",
                "+5555555555" };
        for (String phoneNumber : phoneNumbers) {
            if (phoneNumber.matches("^[+][0-9]{1,3}[-][[(]{0,1}[0-9]+[-)\\s]{0,1}]*[0-9]{4}$")) {
                System.out.println(phoneNumber + " passed validation");
            } else {
                System.out.println(phoneNumber + " failed validation");
            }
        }
    }
}

Output:

+1-555-5555 passed validation
+12-5555555 passed validation
+123-(555) 555-5555 passed validation
+1(555) 555-5555 failed validation
5555555555 failed validation
+5555555555 failed validation
Related