23

In the following ip address validation i want to see if it a valid ip address or not how can i do this using the below re

>>> ip="241.1.1.112343434" 
>>> aa=re.match(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[^0-9]",ip)
>>> aa.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
1
  • 3
    regex is a crappy way to check ip addresses. you have to match numbers up to 255, but not 256, so the regex to do this properly is rather large Commented Apr 10, 2012 at 10:03

5 Answers 5

44

Why not use a library function to validate the ip address?

>>> ip="241.1.1.112343434" 
>>> socket.inet_aton(ip)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
socket.error: illegal IP address string passed to inet_aton
Sign up to request clarification or add additional context in comments.

4 Comments

Only one thing here. If you use this approach 1 also will be suitable ip address according man page.
@Phoenix, yes 1 is equivalent to 0.0.0.1 (as it should be). This is why you should prefer specialised library functions to regex hacks.
This is the best approach IMO. Regex hacks are always prone to errors and using a builtin for such validations should be the first choice.
Old answer but still relevant, I would argue that this is not a perfect approach, considering the use case where OP needs to ensure that the original string needs to be in the form XXX.XXX.XXX.XXXXX. Using the socket.inet_aton would allow an ip of "1", which as mentioned above by @JohnLaRooy is indeed a valid IP address, but it may not be valid where the string must contain 4 octets and a port (which is a requirement unspecified by OP). In this case, I would consider using a combination of socket.inet_aton and the regex approachs
39

Use anchors instead:

aa=re.match(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$",ip)

These make sure that the start and end of the string are matched at the start and end of the regex. (well, technically, you don't need the starting ^ anchor because it's implicit in the .match() method).

Then, check if the regex did in fact match before trying to access its results:

if aa:
    ip = aa.group()

Of course, this is not a good approach for validating IP addresses (check out gnibbler's answer for a proper method). However, regexes can be useful for detecting IP addresses in a larger string:

ip_candidates = re.findall(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b", ip)

Here, the \b word boundary anchors make sure that the digits don't exceed 3 for each segment.

2 Comments

It would be failed on 111.111.111.345 that is outside the range of ip addresses.
import re def is_valid_ip(ip): ipv = re.match(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$",ip) return bool(ipv) and all(map(lambda n: 0<=int(n)<=255, ipv.groups())) ip = input("Enter the ip address for validation:") print (is_valid_ip(ip))
22

\d{1,3} will match numbers like 00 or 333 as well which wouldn't be a valid ID.

This is an excellent answer from smink, citing:

ValidIpAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";

2 Comments

this fails to validate 0.0.0.0
@paltaa Not true. This does validate 0.0.0.0
17
try:
    parts = ip.split('.')
    return len(parts) == 4 and all(0 <= int(part) < 256 for part in parts)
except ValueError:
    return False # one of the 'parts' not convertible to integer
except (AttributeError, TypeError):
    return False # `ip` isn't even a string

3 Comments

If you're going for even stricter validation, I'd replace the validation for return len(parts) == 4 and all(0 < len(part) < 4 and 0 <= int(part) < 256 for part in parts), just in case we encounter a string like this: 1.1.00000000003.1.
@LuissRicardo In what instance would an ip address look like that? Or even be returned in that format?
The point is exactly to make sure that we weren't given something that isn't an IP address.
5

The following will check whether an IP is valid or not: If the IP is within 0.0.0.0 to 255.255.255.255, then the output will be true, otherwise it will be false:

[0<=int(x)<256 for x in re.split('\.',re.match(r'^\d+\.\d+\.\d+\.\d+$',your_ip).group(0))].count(True)==4

Example:

your_ip = "10.10.10.10"
[0<=int(x)<256 for x in re.split('\.',re.match(r'^\d+\.\d+\.\d+\.\d+$',your_ip).group(0))].count(True)==4

Output:

>>> your_ip = "10.10.10.10"
>>> [0<=int(x)<256 for x in re.split('\.',re.match(r'^\d+\.\d+\.\d+\.\d+$',your_ip).group(0))].count(True)==4
True
>>> your_ip = "10.10.10.256"
>>> [0<=int(x)<256 for x in re.split('\.',re.match(r'^\d+\.\d+\.\d+\.\d+$',your_ip).group(0))].count(True)==4
False
>>>

5 Comments

Have you really run this code to show output? I doubt as your-ip is an invalid variable name. Also I see this answer has been put very lately, but the other answers are much more readable.
its a typo mistake would have put '_' instead. yes had run the code and got correct output. let me know if any thing wrong
The point was- A piece of code was posted with a typo, which can not be executed yet output is shown. If you want to show output, please make sure you post the same code that's executed, not anything else.
yes Posted the executed code. Thanks for pointing out.
this would match something like 0.00004.00009.0123

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.