Main Tutorials

Java IP Address (IPv4) regex examples

ipv4 regex

This article focus on how to validate an IP address (IPv4) using regex and Apache Commons Validator.

Here is the summary.

  1. IPv4 regex explanation.
  2. Java IPv4 validator, using regex.
  3. Java IPv4 validator, using commons-validator-1.7
  4. JUnit 5 unit tests for the above IPv4 validators.

IPv4 regex final version.


^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.(?!$)|$)){4}$

# Explanation
(
  [0-9]         # 0-9
  |             # or
  [1-9][0-9]    # 10-99
  |             # or
  1[0-9][0-9]   # 100-199
  |             # or
  2[0-4][0-9]   # 200-249
  |             # or
  25[0-5]       # 250-255
)
(\.(?!$)|$))    # ensure IPv4 doesn't end with a dot
{4}             # 4 times.

P.S This regex is for IPv4 address only. It doesn’t support IPv4 subnet or IPv6.

1. IPv4 Regex Explanation.

The valid IPv4 range is from 0.0.0.0 to 255.255.255.255, we need to create a regex to ensure the number in range [0-255] and dots in the proper position.

1.1 Below is the first IPv4 regex. Later, we will evolve it into a better and shorter version.


  // version 1 allow leading zero, 01.01.01.01
  private static final String IPV4_PATTERN_ALLOW_LEADING_ZERO =
            "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

1.2 The above regex is using the \\d to match numbers 0-9. However, the \\d will also match Unicode numbers; for safety reasons, please use [0-9] to match only the ASCII numbers.

Below is the IPv4 regex version 2.


  // version 2 , allow leading zero, 01.01.01.01
  private static final String IPV4_PATTERN_ALLOW_LEADING_ZERO =
            "^([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$";

Below is the explanation for the above regex.


^                       #  start of the line
  (                     #  start of group #1
    [01]?[0-9][0-9]?    #  can be one or two digits. If three digits appear, it must start either 0 or 1
    |                   #    ...or
    2[0-4][0-9]         #    start with 2, follow by 0-4 and end with any digit (2[0-4][0-9])
    |                   #    ...or
    25[0-5]             #    start with 2, follow by 5 and ends with 0-5 (25[0-5])
  )                     #  end of group  #1
  \\.                   #  follow by a dot "."
                        # repeat it 3 times (3x)
$                       # end of the line

1.3 However, version 1 and version 2 support in the leading zero in IPv4 address, e.g., 01.01.01.01. Is leading zero a valid IPv4 address?

Below is the IPv4 regex version 3; it doesn’t allow the leading zero in an IPv4 address.


  // version 3, simple and easy to understand
  private static final String IPV4_PATTERN =
           "^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$";

Below is the explanation for the above regex; it is a tedious and lengthy regex, but it is much readable and super easy to understand.


(
  [0-9]         # 0-9
  |             # or
  [1-9][0-9]    # 10-99
  |             # or
  1[0-9][0-9]   # 100-199
  |             # or
  2[0-4][0-9]   # 200-249
  |             # or
  25[0-5]       # 250-255
)
\\.             # follow by a dot
                # repeat 3 times.

1.4 Below is the IPv4 regex version 4; it works the same as the above version 3, just a bit shorter regex with repeat {3}.


  // version 4
  private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}" +
            "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"

1.5 Below is the IPv4 regex version 5, a final version. It works the same as version 3 and 4, but shorter and extra (\\.(?!$)|$) to ensure the IPv4 doesn’t end with a dot.


  //version 5
  private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!$)|$)){4}$";

Note
Please refer to the below #4 unit tests for a list of valid and invalid IPv4 addresses.

Extra
Below is a much shorter IPv4 regex version, just for reference. However, I still prefer the above IPv4 regex final version 3 and version 5.


  // 25[0-5]        = 250-255
  // (2[0-4])[0-9]  = 200-249
  // (1[0-9])[0-9]  = 100-199
  // ([1-9])[0-9]   = 10-99
  // [0-9]          = 0-9
  // (\.(?!$))      = can't end with a dot
  private static final String IPV4_PATTERN_SHORTEST =
          "^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$";          

P.S Please don’t use a regex that you don’t understand how it works.

2. Java IPv4 Regex Validator

Below is a Java IPv4 regex validator example. It uses the above IPv4 regex version 5 to validation an IPv4 address.

IPv4ValidatorRegex.java

package com.mkyong.regex.ipv4;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPv4ValidatorRegex {

    private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!$)|$)){4}$";

    private static final Pattern pattern = Pattern.compile(IPV4_PATTERN);

    public static boolean isValid(final String email) {
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

}

3. IPv4 Validator – Apache Commons Validator

This example uses the Apache Commons Validator to validate an IPv4 address.

pom.xml

  <dependency>
      <groupId>commons-validator</groupId>
      <artifactId>commons-validator</artifactId>
      <version>1.7</version>
  </dependency>

Below is another Java IPv4 validator, using the commons-validator APIs to validate an IPv4 address.

IPv4ValidatorApache.java

package com.mkyong.regex.ipv4;

import org.apache.commons.validator.routines.InetAddressValidator;

public class IPv4ValidatorApache {

    private static final InetAddressValidator validator
                              = InetAddressValidator.getInstance();

    public static boolean isValid(final String ip) {

        // only IPv4
        return validator.isValidInet4Address(ip);

        // IPv4 + IPv6
        // return validator.isValid(ip);

        // IPv6 only
        // return validator.isValidInet6Address(ip);
    }

}

Internally, the InetAddressValidator uses simple regex and manual checking to validate an IPv4 address.

InetAddressValidator.java

public class InetAddressValidator implements Serializable {

  private static final String IPV4_REGEX =
              "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";

  //...

  public boolean isValidInet4Address(String inet4Address) {
      // verify that address conforms to generic IPv4 format
      String[] groups = ipv4Validator.match(inet4Address);

      if (groups == null) {
          return false;
      }

      // verify that address subgroups are legal
      for (String ipSegment : groups) {
          if (ipSegment == null || ipSegment.length() == 0) {
              return false;
          }

          int iIpSegment = 0;

          try {
              iIpSegment = Integer.parseInt(ipSegment);
          } catch(NumberFormatException e) {
              return false;
          }

          if (iIpSegment > IPV4_MAX_OCTET_VALUE) {
              return false;
          }

          if (ipSegment.length() > 1 && ipSegment.startsWith("0")) {
              return false;
          }

      }

      return true;
  }

4. Unit Tests (JUnit 5)

Below are JUnit 5 parameterized tests for the above Java validators – #2 IPv4 regex validator and #3 Apache Commons Validator.

pom.xml

  <!-- JUnit 5 -->
  <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-params</artifactId>
      <version>5.4.0</version>
      <scope>test</scope>
  </dependency>
IPv4ValidatorTest.java

package com.mkyong.regex.ipv4;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class IPv4ValidatorTest {

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("validIPv4Provider")
    void test_ipv4_apache_valid(String ipv4) {
        assertTrue(IPv4ValidatorApache.isValid(ipv4));
    }

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("invalidIPv4Provider")
    void test_ipv4_apache_invalid(String ipv4) {
        assertFalse(IPv4ValidatorApache.isValid(ipv4));
    }

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("validIPv4Provider")
    void test_ipv4_regex_valid(String ipv4) {
        assertTrue(IPv4ValidatorRegex.isValid(ipv4));
    }

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("invalidIPv4Provider")
    void test_ipv4_regex_invalid(String ipv4) {
        assertFalse(IPv4ValidatorRegex.isValid(ipv4));
    }

    static Stream<String> validIPv4Provider() {
        return Stream.of(
                "0.0.0.0",
                "0.0.0.1",
                "127.0.0.1",
                "1.2.3.4",              // 0-9
                "11.1.1.0",             // 10-99
                "101.1.1.0",            // 100-199
                "201.1.1.0",            // 200-249
                "255.255.255.255",      // 250-255
                "192.168.1.1",
                "192.168.1.255",
                "100.100.100.100");
    }

    static Stream<String> invalidIPv4Provider() {
        return Stream.of(
                "000.000.000.000",          // leading 0
                "00.00.00.00",              // leading 0
                "1.2.3.04",                 // leading 0
                "1.02.03.4",                // leading 0
                "1.2",                      // 1 dot
                "1.2.3",                    // 2 dots
                "1.2.3.4.5",                // 4 dots
                "192.168.1.1.1",            // 4 dots
                "256.1.1.1",                // 256
                "1.256.1.1",                // 256
                "1.1.256.1",                // 256
                "1.1.1.256",                // 256
                "-100.1.1.1",               // -100
                "1.-100.1.1",               // -100
                "1.1.-100.1",               // -100
                "1.1.1.-100",               // -100
                "1...1",                    // empty between .
                "1..1",                     // empty between .
                "1.1.1.1.",                 // last .
                "");                        // empty
    }

}

All unit tests are passed.

unit tests for ipv4 validators

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-regex/ipv4

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
13 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Arpith
10 years ago

Does not work for 10.106.2142 (2 digits and a 4-digit octet but it is still a valid IP; ping it if you will)

django
2 years ago

Fails for this input “000.12.12.034”

Kevin Rowe
4 years ago

I see lots of problems with this. For example, “255.255.255.255” is NOT a valid IP address; it is a broadcast address. On the other side, “10.10” IS a valid address, it is the equivalent of “10.10.0.0” and your apps should probably fill in the last couple octets when it encounters this type of address.

To do this properly, you’d probably also want to at least provide an option for specifying the subnet mask to use so that you can distinguish broadcast addresses. I would HIGHLY recommend that you parse each octet into a byte array instead of using RegEx. You’ll thank me now and again when you have to review this code a year from now and you have to figure it out again.

mbsysde99
6 years ago

Thank you brother for sharing it. How to validate subnet mask? Anybody can help me?

Neil
5 years ago
Reply to  mbsysde99

private static final String IPV4REGEX = “^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.” +
“([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.” +
“([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.” +
“([01]?\\d\\d?|2[0-4]\\d|25[0-5])(/([0-2]?\\d|3[0-2]))?$”

yash
10 years ago

can you please help me with IPv6 validation using regex, please ?? thanks.

ozgun
11 years ago

IPAddressValidator ipAddressValidator;
ipAddressValidator = new IPAddressValidator();
InetAddress address = null;

boolean valid = ipAddressValidator.validate(“01.03.01.04”);
System.out.println(“IPAddress is valid : ” + ” , ” + valid);

try {
address = InetAddress.getByName(“01.0.000.05”);
} catch (UnknownHostException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}

passerby
8 years ago
Reply to  ozgun

A string of digits beginning with 0 and including just digits 0-7 in an IPv4 address will be taken as an octal numeral, not a decimal numeral, in many contexts, such as the destination in a ping command. Mkyong’s pattern permits 2-digit & 3-digit strings beginning with 0. If the intention is to require a dotted quad of decimal unsigned integers, then multidigit strings beginning with 0 should not be permitted. Ozgun’s getByName approach is better. I think it will handle hostnames & all numeric-string IPv4 addresses, with 3, 2, 1, or 0 dots (4, 3, 2, or 1 unsigned-integer parts, with each part in decimal, hexadecimal (0x… or 0X…), or octal (0…) form, independent of the other part(s)). The getHostAddress method of an InetAddress object may be used to produce the standard (decimal-only dotted quad) text-string form of the IPv4 address.

Vijay Bhaskar Semwal
13 years ago

Regular expression for Floating Point Number

The use of nearly duplicate expressions joined with the or operator “|” to permit the decimal point to lead or follow digits.

{[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?}
[-+]?([0-9]+\.?[0-9]* .. will lead e.g= -2.0129…
[-+]?([0-9]+\.[0-9]+)([eE][-+]?[0-9]+) .. will lead e.g – 2.3+e123
Vijay Bhaskar Semwal
B.tech.+M.tech.
IIIT Allahabad

Jaime
13 years ago

127.000.000.001
000.000.000.000

Matches too, which would be the best way to modify regex to disallow it?