Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Overview

Sometimes, we need to validate text to ensure that its content complies with some format. In this quick tutorial, we'll see how to validate different formats of phone numbers using regular expressions.

2. Regular Expressions to Validate Phone Numbers

2.1. Ten-Digit Number

Let's start with a simple expression that will check if the number has ten digits and nothing else:

@Test
public void whenMatchesTenDigitsNumber_thenCorrect() {
    Pattern pattern = Pattern.compile("^\\d{10}$");
    Matcher matcher = pattern.matcher("2055550125");
    assertTrue(matcher.matches());
}

This expression will allow numbers like 2055550125.

2.2. Number With Whitespaces, Dots or Hyphens

In the second example, let's see how we can allow optional whitespace, dots, or hyphens (-) between the numbers:

@Test
public void whenMatchesTenDigitsNumberWhitespacesDotHyphen_thenCorrect() {
    Pattern pattern = Pattern.compile("^(\\d{3}[- .]?){2}\\d{4}$");
    Matcher matcher = pattern.matcher("202 555 0125");
    assertTrue(matcher.matches());
}

To achieve this extra goal (optional whitespace or hyphen), we've simply added the characters:

  • [- .]?

This pattern will allow numbers like 2055550125, 202 555 0125, 202.555.0125, and 202-555-0125.

2.3. Number With Parentheses

Next, let's add the possibility to have the first part of our phone between parentheses:

@Test
public void whenMatchesTenDigitsNumberParenthesis_thenCorrect() {
    Pattern pattern = Pattern.compile"^((\\(\\d{3}\\))|\\d{3})[- .]?\\d{3}[- .]?\\d{4}$");
    Matcher matcher = pattern.matcher("(202) 555-0125");
    assertTrue(matcher.matches());
}

To allow the optional parenthesis in the number, we've added the following characters to our regular expression:

  • (\\(\\d{3}\\))|\\d{3})

This expression will allow numbers like (202)5550125, (202) 555-0125 or (202)-555-0125. Additionally, this expression will also allow the phone numbers covered in the previous example.

2.4. Number With International Prefix

Finally, let's see how to allow an international prefix at the start of a phone number:

@Test
public void whenMatchesTenDigitsNumberPrefix_thenCorrect() {
  Pattern pattern = Pattern.compile("^(\\+\\d{1,3}( )?)?((\\(\\d{3}\\))|\\d{3})[- .]?\\d{3}[- .]?\\d{4}$");
  Matcher matcher = pattern.matcher("+111 (202) 555-0125");
  
  assertTrue(matcher.matches());
}

To permit the prefix in our number, we have added to the beginning of our pattern the characters:

  • (\\+\\d{1,3}( )?)?

This expression will enable phone numbers to include international prefixes, taking into account that international prefixes are normally numbers with a maximum of three digits.

3. Applying Multiple Regular Expressions

As we've seen, a valid phone number can take on several different formats. Therefore, we may want to check if our String complies with any one of these formats.

In the last section, we started with a simple expression and added more complexity to achieve the goal of covering more than one format. However, sometimes it's not possible to use just one expression. In this section, we'll see how to join multiple regular expressions into a single one.

If we are unable to create a common regular expression that can validate all the possible cases that we want to cover, we can define different expressions for each of the cases and then use them all together by concatenating them with a pipe symbol (|).

Let's see an example where we use the following expressions:

  • The expression used in the last section:
    • ^(\\+\\d{1,3}( )?)?((\\(\\d{3}\\))|\\d{3})[- .]?\\d{3}[- .]?\\d{4}$
  • Regular expression to allow numbers like +111 123 456 789:
    • ^(\\+\\d{1,3}( )?)?(\\d{3}[ ]?){2}\\d{3}$
  • Pattern to allow numbers like +111 123 45 67 89:
    • ^(\\+\\d{1,3}( )?)?(\\d{3}[ ]?)(\\d{2}[ ]?){2}\\d{2}$
@Test
public void whenMatchesPhoneNumber_thenCorrect() {
    String patterns 
      = "^(\\+\\d{1,3}( )?)?((\\(\\d{3}\\))|\\d{3})[- .]?\\d{3}[- .]?\\d{4}$" 
      + "|^(\\+\\d{1,3}( )?)?(\\d{3}[ ]?){2}\\d{3}$" 
      + "|^(\\+\\d{1,3}( )?)?(\\d{3}[ ]?)(\\d{2}[ ]?){2}\\d{2}$";

    String[] validPhoneNumbers 
      = {"2055550125","202 555 0125", "(202) 555-0125", "+111 (202) 555-0125", 
      "636 856 789", "+111 636 856 789", "636 85 67 89", "+111 636 85 67 89"};

    Pattern pattern = Pattern.compile(patterns);
    for(String phoneNumber : validPhoneNumbers) {
        Matcher matcher = pattern.matcher(phoneNumber);
        assertTrue(matcher.matches());
    }
}

As we can see in the above example, by using the pipe symbol, we can use the three expressions in one go, thus allowing us to cover more cases than with just one regular expression.

4. Conclusion

In this article, we've seen how to check whether a String contains a valid phone number using different regular expressions. We've also learned how to use multiple regular expressions at the same time.

As always, the full source code of the article is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Chas B
Chas B
3 months ago

For phone numbers, may find using Google libphonenumber is better than regex: https://github.com/google/libphonenumber

Loredana Crusoveanu
2 months ago
Reply to  Chas B

Hi Chas,
Thanks for the feedback. In this article, we focus on the Java Regex only.
However, libphonenumber seems to be pretty interesting. We might write a dedicated article in the future.
Cheers

Comments are closed on this article!