IP Address Validation Regular Expressions

IP addresses are numerical labels assigned to devices on a network. There are two versions in use: IPv4 (defined in RFC 791) and IPv6 (defined in RFC 4291). These regex patterns validate the format of both IPv4 and IPv6 addresses. IP addresses can be used in URLs as an alternative to domain names.

IPv4 Address Validation

IPv4 addresses consist of four octets (0-255) separated by dots.

^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$

Explanation

  • ^ - Start of the string.
  • (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3} - Three octets followed by dots:
    • 25[0-5] - Matches 250-255.
    • 2[0-4][0-9] - Matches 200-249.
    • [01]?[0-9][0-9]? - Matches 0-199.
  • (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) - Fourth octet (same pattern, no trailing dot).
  • $ - End of the string.

Implementation

const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
const isValidIPv4 = (ip) => ipv4Regex.test(ip);

Test Cases

IPv4 AddressValid
192.168.1.1
0.0.0.0
255.255.255.255
10.0.0.1
172.16.0.1
8.8.8.8
127.0.0.1
1.1.1.1
256.1.1.1
192.168.1.256
192.168.1
192.168.1.1.1
192.168.-1.1
192.168.1.1.1
abc.def.ghi.jkl
(empty string)
192.168.1.01
999.999.999.999

IPv6 Address Validation

IPv6 addresses consist of eight groups of four hexadecimal digits separated by colons, with support for compressed notation using "::".

^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,6}:$|^(?:[0-9a-fA-F]{1,4}:)(?::[0-9a-fA-F]{1,4}){1,6}$|^(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,5}$|^(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4}$

Explanation

The IPv6 regex pattern is complex due to the various valid compression formats. It includes multiple alternatives to match:

  • Full format: Eight groups of hex digits separated by colons.
  • Compressed format starting with :: (e.g., ::1).
  • Compressed format ending with :: (e.g., 2001:db8::).
  • Compressed format with :: in the middle (e.g., 2001:db8::8a2e:370:7334).

Implementation

const ipv6Regex = /^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){1,6}:$|^(?:[0-9a-fA-F]{1,4}:)(?::[0-9a-fA-F]{1,4}){1,6}$|^(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,5}$|^(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,4}$|^(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,3}$|^(?:[0-9a-fA-F]{1,4}:){5}(?::[0-9a-fA-F]{1,4}){1,2}$|^(?:[0-9a-fA-F]{1,4}:){6}:[0-9a-fA-F]{1,4}$/;
const isValidIPv6 = (ip) => ipv6Regex.test(ip);

Test Cases

IPv6 AddressValid
2001:0db8:85a3:0000:0000:8a2e:0370:7334
2001:db8:85a3::8a2e:370:7334
::1
::
fe80::1
::ffff:192.0.2.1
2001:db8::8a2e:370:7334
2001:0db8:0001:0000:0000:0ab9:C0A8:0102
2001:db8:85a3:0:0:8a2e:370:7334
::ffff:c000:0280
02001:0db8:0000:0000:0000:ff00:0042:8329
2001:0db8:0000:0000:0000:ff00:0042:83290
2001:db8:::8a2e:370:7334
gggg::1111
(empty string)

Notes

  • For production use, consider using built-in IP address parsing libraries instead of regex for more robust validation.
  • IPv4 addresses with leading zeros (e.g., 192.168.001.001) are accepted by this pattern but may be interpreted as octal in some contexts.
  • The IPv6 pattern does not validate IPv4-mapped IPv6 addresses (e.g., ::ffff:192.0.2.1).
  • Private IP ranges (e.g., 192.168.x.x, 10.x.x.x) are validated for format but not distinguished from public IPs.
  • These patterns validate format only and do not check if an IP is reachable or assigned.