What's the best way to validate that an IP entered by the user is valid? It comes in as a string.
This question is related to
python
validation
networking
ip-address
I think this would do it...
def validIP(address):
parts = address.split(".")
if len(parts) != 4:
return False
for item in parts:
if not 0 <= int(item) <= 255:
return False
return True
I have to give a great deal of credit to Markus Jarderot for his post - the majority of my post is inspired from his.
I found that Markus' answer still fails some of the IPv6 examples in the Perl script referenced by his answer.
Here is my regex that passes all of the examples in that Perl script:
r"""^
\s* # Leading whitespace
# Zero-width lookaheads to reject too many quartets
(?:
# 6 quartets, ending IPv4 address; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){6}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-5 quartets, wildcard, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-4 quartets, wildcard, 0-1 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:)))?
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-3 quartets, wildcard, 0-2 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,2}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-2 quartets, wildcard, 0-3 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,3}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-1 quartets, wildcard, 0-4 quartets, ending IPv4 address
(?:[0-9a-f]{1,4}){0,1}
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,4}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# wildcard, 0-5 quartets, ending IPv4 address
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,5}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 8 quartets; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){7}[0-9a-f]{1,4}
|
# 0-7 quartets, wildcard
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
(?:::(?!:))
|
# 0-6 quartets, wildcard, 0-1 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4})?
|
# 0-5 quartets, wildcard, 0-2 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
|
# 0-4 quartets, wildcard, 0-3 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
|
# 0-3 quartets, wildcard, 0-4 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
|
# 0-2 quartets, wildcard, 0-5 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
|
# 0-1 quartets, wildcard, 0-6 quartets
(?:[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
|
# wildcard, 0-7 quartets
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
)
(?:/(?:1(?:2[0-7]|[01]\d)|\d\d?))? # With an optional CIDR routing prefix (0-128)
\s* # Trailing whitespace
$"""
I also put together a Python script to test all of those IPv6 examples; it's here on Pastebin because it was too large to post here.
You can run the script with test result and example arguments in the form of "[result]=[example]", so like:
python script.py Fail=::1.2.3.4: pass=::127.0.0.1 false=::: True=::1
or you can simply run all of the tests by specifying no arguments, so like:
python script.py
Anyway, I hope this helps somebody else!
The IPy module (a module designed for dealing with IP addresses) will throw a ValueError exception for invalid addresses.
>>> from IPy import IP
>>> IP('127.0.0.1')
IP('127.0.0.1')
>>> IP('277.0.0.1')
Traceback (most recent call last):
...
ValueError: '277.0.0.1': single byte must be 0 <= byte < 256
>>> IP('foobar')
Traceback (most recent call last):
...
ValueError: invalid literal for long() with base 10: 'foobar'
However, like Dustin's answer, it will accept things like "4" and "192.168" since, as mentioned, these are valid representations of IP addresses.
If you're using Python 3.3 or later, it now includes the ipaddress module:
>>> import ipaddress
>>> ipaddress.ip_address('127.0.0.1')
IPv4Address('127.0.0.1')
>>> ipaddress.ip_address('277.0.0.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: '277.0.0.1' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.ip_address('foobar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: 'foobar' does not appear to be an IPv4 or IPv6 address
For Python 2, you can get the same functionality using ipaddress if you install python-ipaddress:
pip install ipaddress
This module is compatible with Python 2 and provides a very similar API to that of the ipaddress module included in the Python Standard Library since Python 3.3. More details here. In Python 2 you will need to explicitly convert the IP address string to unicode: ipaddress.ip_address(u'127.0.0.1')
.
import socket
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def is_valid_ipv6_address(address):
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error: # not a valid address
return False
return True
From Python 3.4 on, the best way to check if an IPv6 or IPv4 address is correct, is to use the Python Standard Library module ipaddress
- IPv4/IPv6 manipulation library s.a. https://docs.python.org/3/library/ipaddress.html for complete documentation.
Example :
#!/usr/bin/env python
import ipaddress
import sys
try:
ip = ipaddress.ip_address(sys.argv[1])
print('%s is a correct IP%s address.' % (ip, ip.version))
except ValueError:
print('address/netmask is invalid: %s' % sys.argv[1])
except:
print('Usage : %s ip' % sys.argv[0])
For other versions: Github, phihag / Philipp Hagemeister,"Python 3.3's ipaddress for older Python versions", https://github.com/phihag/ipaddress
The backport from phihag is available e.g. in Anaconda Python 2.7 & is included in Installer. s.a. https://docs.continuum.io/anaconda/pkg-docs
To install with pip:
pip install ipaddress
s.a.: ipaddress 1.0.17, "IPv4/IPv6 manipulation library", "Port of the 3.3+ ipaddress module", https://pypi.python.org/pypi/ipaddress/1.0.17
I have to give a great deal of credit to Markus Jarderot for his post - the majority of my post is inspired from his.
I found that Markus' answer still fails some of the IPv6 examples in the Perl script referenced by his answer.
Here is my regex that passes all of the examples in that Perl script:
r"""^
\s* # Leading whitespace
# Zero-width lookaheads to reject too many quartets
(?:
# 6 quartets, ending IPv4 address; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){6}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-5 quartets, wildcard, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-4 quartets, wildcard, 0-1 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:)))?
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-3 quartets, wildcard, 0-2 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,2}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-2 quartets, wildcard, 0-3 quartets, ending IPv4 address
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,3}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 0-1 quartets, wildcard, 0-4 quartets, ending IPv4 address
(?:[0-9a-f]{1,4}){0,1}
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,4}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# wildcard, 0-5 quartets, ending IPv4 address
(?:::(?!:))
(?:[0-9a-f]{1,4}(?::(?!:))){0,5}
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)
(?:\.(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}
|
# 8 quartets; no wildcards
(?:[0-9a-f]{1,4}(?::(?!:))){7}[0-9a-f]{1,4}
|
# 0-7 quartets, wildcard
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
(?:::(?!:))
|
# 0-6 quartets, wildcard, 0-1 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
(?:::(?!:))
(?:[0-9a-f]{1,4})?
|
# 0-5 quartets, wildcard, 0-2 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
|
# 0-4 quartets, wildcard, 0-3 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
|
# 0-3 quartets, wildcard, 0-4 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,2}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,3}[0-9a-f]{1,4})?
|
# 0-2 quartets, wildcard, 0-5 quartets
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,1}[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,4}[0-9a-f]{1,4})?
|
# 0-1 quartets, wildcard, 0-6 quartets
(?:[0-9a-f]{1,4})?
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,5}[0-9a-f]{1,4})?
|
# wildcard, 0-7 quartets
(?:::(?!:))
(?:(?:[0-9a-f]{1,4}(?::(?!:))){0,6}[0-9a-f]{1,4})?
)
(?:/(?:1(?:2[0-7]|[01]\d)|\d\d?))? # With an optional CIDR routing prefix (0-128)
\s* # Trailing whitespace
$"""
I also put together a Python script to test all of those IPv6 examples; it's here on Pastebin because it was too large to post here.
You can run the script with test result and example arguments in the form of "[result]=[example]", so like:
python script.py Fail=::1.2.3.4: pass=::127.0.0.1 false=::: True=::1
or you can simply run all of the tests by specifying no arguments, so like:
python script.py
Anyway, I hope this helps somebody else!
I think this would do it...
def validIP(address):
parts = address.split(".")
if len(parts) != 4:
return False
for item in parts:
if not 0 <= int(item) <= 255:
return False
return True
I came up with this noob simple version
def ip_checkv4(ip):
parts=ip.split(".")
if len(parts)<4 or len(parts)>4:
return "invalid IP length should be 4 not greater or less than 4"
else:
while len(parts)== 4:
a=int(parts[0])
b=int(parts[1])
c=int(parts[2])
d=int(parts[3])
if a<= 0 or a == 127 :
return "invalid IP address"
elif d == 0:
return "host id should not be 0 or less than zero "
elif a>=255:
return "should not be 255 or greater than 255 or less than 0 A"
elif b>=255 or b<0:
return "should not be 255 or greater than 255 or less than 0 B"
elif c>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 C"
elif d>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 D"
else:
return "Valid IP address ", ip
p=raw_input("Enter IP address")
print ip_checkv4(p)
I only needed to parse IP v4 addresses. My solution based on Chills strategy follows:
def getIP():
valid = False
while not valid :
octets = raw_input( "Remote Machine IP Address:" ).strip().split(".")
try: valid=len( filter( lambda(item):0<=int(item)<256, octets) ) == 4
except: valid = False
return ".".join( octets )
def is_valid_ip(ip):
"""Validates IP addresses.
"""
return is_valid_ipv4(ip) or is_valid_ipv6(ip)
IPv4:
def is_valid_ipv4(ip):
"""Validates IPv4 addresses.
"""
pattern = re.compile(r"""
^
(?:
# Dotted variants:
(?:
# Decimal 1-255 (no leading 0's)
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's)
|
0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
)
(?: # Repeat 0-3 times, separated by a dot
\.
(?:
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2}
|
0+[1-3]?[0-7]{0,2}
)
){0,3}
|
0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff
|
0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777
|
# Decimal notation, 1-4294967295:
429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
)
$
""", re.VERBOSE | re.IGNORECASE)
return pattern.match(ip) is not None
IPv6:
def is_valid_ipv6(ip):
"""Validates IPv6 addresses.
"""
pattern = re.compile(r"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
){6} #
(?: # Either
[0-9a-f]{0,4} # Another group
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
[0-9a-f]{0,4} # Last group
(?: (?<=::) # Colon iff preceeded by exacly one colon
| (?<!:) #
| (?<=:) (?<!::) : #
) # OR
| # A v4 address with NO leading zeros
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
(?: \.
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
){3}
)
\s* # Trailing whitespace
$
""", re.VERBOSE | re.IGNORECASE | re.DOTALL)
return pattern.match(ip) is not None
The IPv6 version uses "(?:(?<=::)|(?<!::):)
", which could be replaced with "(?(?<!::):)
" on regex engines that support conditionals with look-arounds. (i.e. PCRE, .NET)
Edit:
Edit2:
I found some links discussing how to parse IPv6 addresses with regex:
Edit3:
Finally managed to write a pattern that passes all tests, and that I am also happy with.
Don't parse it. Just ask.
import socket
try:
socket.inet_aton(addr)
# legal
except socket.error:
# Not legal
import socket
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def is_valid_ipv6_address(address):
try:
socket.inet_pton(socket.AF_INET6, address)
except socket.error: # not a valid address
return False
return True
I think this would do it...
def validIP(address):
parts = address.split(".")
if len(parts) != 4:
return False
for item in parts:
if not 0 <= int(item) <= 255:
return False
return True
The IPy module (a module designed for dealing with IP addresses) will throw a ValueError exception for invalid addresses.
>>> from IPy import IP
>>> IP('127.0.0.1')
IP('127.0.0.1')
>>> IP('277.0.0.1')
Traceback (most recent call last):
...
ValueError: '277.0.0.1': single byte must be 0 <= byte < 256
>>> IP('foobar')
Traceback (most recent call last):
...
ValueError: invalid literal for long() with base 10: 'foobar'
However, like Dustin's answer, it will accept things like "4" and "192.168" since, as mentioned, these are valid representations of IP addresses.
If you're using Python 3.3 or later, it now includes the ipaddress module:
>>> import ipaddress
>>> ipaddress.ip_address('127.0.0.1')
IPv4Address('127.0.0.1')
>>> ipaddress.ip_address('277.0.0.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: '277.0.0.1' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.ip_address('foobar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: 'foobar' does not appear to be an IPv4 or IPv6 address
For Python 2, you can get the same functionality using ipaddress if you install python-ipaddress:
pip install ipaddress
This module is compatible with Python 2 and provides a very similar API to that of the ipaddress module included in the Python Standard Library since Python 3.3. More details here. In Python 2 you will need to explicitly convert the IP address string to unicode: ipaddress.ip_address(u'127.0.0.1')
.
Don't parse it. Just ask.
import socket
try:
socket.inet_aton(addr)
# legal
except socket.error:
# Not legal
I hope it's simple and pythonic enough:
def is_valid_ip(ip):
m = re.match(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$", ip)
return bool(m) and all(map(lambda n: 0 <= int(n) <= 255, m.groups()))
From Python 3.4 on, the best way to check if an IPv6 or IPv4 address is correct, is to use the Python Standard Library module ipaddress
- IPv4/IPv6 manipulation library s.a. https://docs.python.org/3/library/ipaddress.html for complete documentation.
Example :
#!/usr/bin/env python
import ipaddress
import sys
try:
ip = ipaddress.ip_address(sys.argv[1])
print('%s is a correct IP%s address.' % (ip, ip.version))
except ValueError:
print('address/netmask is invalid: %s' % sys.argv[1])
except:
print('Usage : %s ip' % sys.argv[0])
For other versions: Github, phihag / Philipp Hagemeister,"Python 3.3's ipaddress for older Python versions", https://github.com/phihag/ipaddress
The backport from phihag is available e.g. in Anaconda Python 2.7 & is included in Installer. s.a. https://docs.continuum.io/anaconda/pkg-docs
To install with pip:
pip install ipaddress
s.a.: ipaddress 1.0.17, "IPv4/IPv6 manipulation library", "Port of the 3.3+ ipaddress module", https://pypi.python.org/pypi/ipaddress/1.0.17
I hope it's simple and pythonic enough:
def is_valid_ip(ip):
m = re.match(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$", ip)
return bool(m) and all(map(lambda n: 0 <= int(n) <= 255, m.groups()))
def is_valid_ip(ip):
"""Validates IP addresses.
"""
return is_valid_ipv4(ip) or is_valid_ipv6(ip)
IPv4:
def is_valid_ipv4(ip):
"""Validates IPv4 addresses.
"""
pattern = re.compile(r"""
^
(?:
# Dotted variants:
(?:
# Decimal 1-255 (no leading 0's)
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's)
|
0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
)
(?: # Repeat 0-3 times, separated by a dot
\.
(?:
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2}
|
0+[1-3]?[0-7]{0,2}
)
){0,3}
|
0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff
|
0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777
|
# Decimal notation, 1-4294967295:
429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
)
$
""", re.VERBOSE | re.IGNORECASE)
return pattern.match(ip) is not None
IPv6:
def is_valid_ipv6(ip):
"""Validates IPv6 addresses.
"""
pattern = re.compile(r"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
){6} #
(?: # Either
[0-9a-f]{0,4} # Another group
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
[0-9a-f]{0,4} # Last group
(?: (?<=::) # Colon iff preceeded by exacly one colon
| (?<!:) #
| (?<=:) (?<!::) : #
) # OR
| # A v4 address with NO leading zeros
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
(?: \.
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
){3}
)
\s* # Trailing whitespace
$
""", re.VERBOSE | re.IGNORECASE | re.DOTALL)
return pattern.match(ip) is not None
The IPv6 version uses "(?:(?<=::)|(?<!::):)
", which could be replaced with "(?(?<!::):)
" on regex engines that support conditionals with look-arounds. (i.e. PCRE, .NET)
Edit:
Edit2:
I found some links discussing how to parse IPv6 addresses with regex:
Edit3:
Finally managed to write a pattern that passes all tests, and that I am also happy with.
I came up with this noob simple version
def ip_checkv4(ip):
parts=ip.split(".")
if len(parts)<4 or len(parts)>4:
return "invalid IP length should be 4 not greater or less than 4"
else:
while len(parts)== 4:
a=int(parts[0])
b=int(parts[1])
c=int(parts[2])
d=int(parts[3])
if a<= 0 or a == 127 :
return "invalid IP address"
elif d == 0:
return "host id should not be 0 or less than zero "
elif a>=255:
return "should not be 255 or greater than 255 or less than 0 A"
elif b>=255 or b<0:
return "should not be 255 or greater than 255 or less than 0 B"
elif c>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 C"
elif d>=255 or c<0:
return "should not be 255 or greater than 255 or less than 0 D"
else:
return "Valid IP address ", ip
p=raw_input("Enter IP address")
print ip_checkv4(p)
Don't parse it. Just ask.
import socket
try:
socket.inet_aton(addr)
# legal
except socket.error:
# Not legal
I think this would do it...
def validIP(address):
parts = address.split(".")
if len(parts) != 4:
return False
for item in parts:
if not 0 <= int(item) <= 255:
return False
return True
def is_valid_ip(ip):
"""Validates IP addresses.
"""
return is_valid_ipv4(ip) or is_valid_ipv6(ip)
IPv4:
def is_valid_ipv4(ip):
"""Validates IPv4 addresses.
"""
pattern = re.compile(r"""
^
(?:
# Dotted variants:
(?:
# Decimal 1-255 (no leading 0's)
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's)
|
0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
)
(?: # Repeat 0-3 times, separated by a dot
\.
(?:
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2}
|
0+[1-3]?[0-7]{0,2}
)
){0,3}
|
0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff
|
0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777
|
# Decimal notation, 1-4294967295:
429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
)
$
""", re.VERBOSE | re.IGNORECASE)
return pattern.match(ip) is not None
IPv6:
def is_valid_ipv6(ip):
"""Validates IPv6 addresses.
"""
pattern = re.compile(r"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
){6} #
(?: # Either
[0-9a-f]{0,4} # Another group
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
[0-9a-f]{0,4} # Last group
(?: (?<=::) # Colon iff preceeded by exacly one colon
| (?<!:) #
| (?<=:) (?<!::) : #
) # OR
| # A v4 address with NO leading zeros
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
(?: \.
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
){3}
)
\s* # Trailing whitespace
$
""", re.VERBOSE | re.IGNORECASE | re.DOTALL)
return pattern.match(ip) is not None
The IPv6 version uses "(?:(?<=::)|(?<!::):)
", which could be replaced with "(?(?<!::):)
" on regex engines that support conditionals with look-arounds. (i.e. PCRE, .NET)
Edit:
Edit2:
I found some links discussing how to parse IPv6 addresses with regex:
Edit3:
Finally managed to write a pattern that passes all tests, and that I am also happy with.
I only needed to parse IP v4 addresses. My solution based on Chills strategy follows:
def getIP():
valid = False
while not valid :
octets = raw_input( "Remote Machine IP Address:" ).strip().split(".")
try: valid=len( filter( lambda(item):0<=int(item)<256, octets) ) == 4
except: valid = False
return ".".join( octets )
Consider IPv4 address as "ip".
if re.match(r'^((\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])$', ip):
print "Valid IP"
else:
print "Invalid IP"
The IPy module (a module designed for dealing with IP addresses) will throw a ValueError exception for invalid addresses.
>>> from IPy import IP
>>> IP('127.0.0.1')
IP('127.0.0.1')
>>> IP('277.0.0.1')
Traceback (most recent call last):
...
ValueError: '277.0.0.1': single byte must be 0 <= byte < 256
>>> IP('foobar')
Traceback (most recent call last):
...
ValueError: invalid literal for long() with base 10: 'foobar'
However, like Dustin's answer, it will accept things like "4" and "192.168" since, as mentioned, these are valid representations of IP addresses.
If you're using Python 3.3 or later, it now includes the ipaddress module:
>>> import ipaddress
>>> ipaddress.ip_address('127.0.0.1')
IPv4Address('127.0.0.1')
>>> ipaddress.ip_address('277.0.0.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: '277.0.0.1' does not appear to be an IPv4 or IPv6 address
>>> ipaddress.ip_address('foobar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.3/ipaddress.py", line 54, in ip_address
address)
ValueError: 'foobar' does not appear to be an IPv4 or IPv6 address
For Python 2, you can get the same functionality using ipaddress if you install python-ipaddress:
pip install ipaddress
This module is compatible with Python 2 and provides a very similar API to that of the ipaddress module included in the Python Standard Library since Python 3.3. More details here. In Python 2 you will need to explicitly convert the IP address string to unicode: ipaddress.ip_address(u'127.0.0.1')
.
Consider IPv4 address as "ip".
if re.match(r'^((\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])$', ip):
print "Valid IP"
else:
print "Invalid IP"
Source: Stackoverflow.com