ManStudent
ManStudent

Reputation: 65

Python regular expression to match IPV4 address doesn't work

I'm using the re library.

def validate_ip(self, ip):
    pattern = re.compile(r'([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.{4}')
    matchObj = re.match(pattern, ip)

    if matchObj == None:
        print "Invalid IP:", ip
        sys.exit(0)

When I pass the IP 192.0.0.0, the output is:

Invalid IP: 192.0.0.0

Why is it not matching?

Upvotes: 4

Views: 3209

Answers (2)

user1907906
user1907906

Reputation:

If you can use Python 3.3+, use the ipaddress library.

import ipaddress

for ip in ["192.0.0.0", "0.0.0.0", "192.168.0.256"]:
    try:
        ipaddress.ip_address(ip)
        print("{} is valid".format(ip));
    except ValueError:
        print("{} is invalid".format(ip))

Output:

192.0.0.0 is valid
0.0.0.0 is valid
192.168.0.256 is invalid

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1122092

Your pattern matches one 3-digit number, followed by exactly 4 dots:

>>> pattern = re.compile(r'([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.{4}')
>>> pattern.match('255....')
<_sre.SRE_Match object at 0x1026eda80>

The {4} doesn't apply to everything preceding it; it only applies to just the \..

You want this instead:

r'(([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.){3}([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])'

This matches your number pattern plus a . dot 3 times, because now the {3} applies to everything in the preceding grouped expression (using (...)). You then still need to match the last digit group separately.

Demo:

>>> pattern = re.compile(r'(([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])\.){3}([01]?[0-9]?[0-9]|2[0-4][0-9]|2[5][0-5])')
>>> pattern.match('192.0.0.0')
<_sre.SRE_Match object at 0x1023bf588>

As an aside, just use if not match: to test for a match failure; None is a false value in a boolean context. Even if you really wanted to test for None, you should be using if match is None:, using an identity test.

Upvotes: 7

Related Questions