Java IP Address (IPv4) regex examples
This article focus on how to validate an IP address (IPv4) using regex and Apache Commons Validator.
Here is the summary.
- IPv4 regex explanation.
- Java IPv4 validator, using regex.
- Java IPv4 validator, using
commons-validator-1.7
- 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.
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.
<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.
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.
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.
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.4.0</version>
<scope>test</scope>
</dependency>
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.
Download Source Code
$ git clone https://github.com/mkyong/core-java
$ cd java-regex/ipv4
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)
It is better to use regex for some generic IPv4 format. And later manual check for specified requirements like your octet case.
Fails for this input “000.12.12.034”
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.
The above regex only supports range from
0.0.0.0
to255.255.255.255
; it doesn’t check broadcast (it is still a valid IP address), subnet, etc.Consider regex and manual checking like what Apache commons validator did (example 3).
Thank you brother for sharing it. How to validate subnet mask? Anybody can help me?
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]))?$”
can you please help me with IPv6 validation using regex, please ?? thanks.
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.
}
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.
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
127.000.000.001
000.000.000.000
Matches too, which would be the best way to modify regex to disallow it?
We updated the examples (many times); it is an invalid IPv4 address. Refer to the #4 unit tests.