An Internet Protocol (IP) address is a numerical label assigned to each device connected to a computer network that uses the Internet .

The most common IP format is IPv4, which is a 32-bit address expressed as four 8-bit octets. It consisting of four numbers separated by a dot that ranges from 0.0.0.0 to 255.255.255.255. For example, the IP address could be 192.168.1.0 In this example, 192 is the first octet, 168 is the second octet, 1 is the third octet, and 0 is the fourth octet.

We can use  the following regular expression pattern to check whether an entry is a valid IPV4 address:

Match with word boundaries

\b(?:(?: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]?)\b
  • \b matches a word boundary to ensure that the IP address is not part of a larger word.
  • (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) is a non-capturing group that matches a segment of the IP address. It allows for three possible formats:
    • 25[0-5] matches the numbers 250 to 255.
    • 2[0-4][0-9] matches the numbers 200 to 249.
    • [01]?[0-9][0-9]? matches the numbers 0 to 199. It allows for zero, one, or two digits, with leading zeros being optional.
  • \. matches the dot (.) separator between segments of the IP address.
  • {3} specifies that the previous group and dot separator should be repeated exactly three times.
  • (?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) is the final segment of the IP address.
  • \b matches a word boundary to ensure that the IP address is not part of a larger word.
import re

text = "The server IP address is 192.168.0.1 and the gateway is 10.0.0.1."
pattern = r'\b(?:(?: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]?)\b'
matches = re.findall(pattern, text)
print(matches)

match full string as an IPV4 address

^(?:(?: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]?)$
  • ^ matches the start of a line or string, ensuring that the IP address starts at the beginning of the given string.
  • $ matches the end of a line or string, ensuring that the IP address ends at the end of the given string.
import re

IP = '192.187.169.35'
pattern = r"^(?:(?: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]?)$"

if re.match(pattern, IP):
   print("The IP is Valid")
else:
   print("Invalid")

IPV6 Addresses

IPv6 (Internet Protocol version 6) is the most recent version of the Internet Protocol (IP)

The IPv6 address format consists of eight groups of four hexadecimal digits separated by colons (:). The addresses range from 0:0:0:0:0:0:0:1 to FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF. Example of IPv6 address is 2001:0db8:0000:0000:0000:ff00:0042:8329

regular expression pattern for matching IPV6 address

Due to the many variations that an IPV6 address can have, the regular expression pattern to match them can be pretty complex and tedious.  We will break it into eight bits, each for one of the eight parts of an IPV6 Address.

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

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

^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$

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

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

^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$

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

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

Putting the whole thing together we get:

^(?:[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}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$|^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$
def is_valid_ipv6(ip):
    import re
    pattern = r"^(?:[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}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$|^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$|^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$"
    return bool(re.match(pattern, ip))

print(is_valid_ipv6('2001:0db8:0000:0000:0000:ff00:0042:8329'))
print(is_valid_ipv6('::1'))