Reputation: 2741
I've been trying to get an efficient regex for IPv4 validation, but without much luck. It seemed at one point I had had it with (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}
, but it produces some strange results:
$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555
I did a search to see if this had already been asked and answered, but other answers appear to simply show how to determine 4 groups of 1-3 numbers, or do not work for me.
Upvotes: 237
Views: 652850
Reputation: 20852
I would consider this the best compromise between readability and conciseness:
^((25[0-5]|2[0-4]\d|[01]?\d?\d)\.?\b){4}$
Here is an extended version that also accepts CIDR-notation for network ranges (i.e. 123.123.123.123/24):
^((25[0-5]|2[0-4]\d|[01]?\d?\d)\.?\b){4}(\/(3[0-2]|[0-2]?\d))?$
Upvotes: 1
Reputation: 18490
The shortest pattern is not necessarily the most efficient. I prefer
^(?:\b\.?(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){4}$
which is a good tradeoff between pattern-length and efficiency.
This pattern works by use of a \b
word boundary and making the dot optional. The word boundary will still require a dot between each 0-255. Placement of \b
disallows a dot at the ^
start.
Certainly by use of (
capturing )
instead of (?:
non-capturing )
groups four characters can be spared but why capture anything without reason? No part gets reused or would be extracted.
The only reason that makes sense would be, if non-capturing groups are not supported.
Without validating 0-255 and allowing any one to three digits: ^(?:\b\.?\d{1,3}){4}$
Upvotes: 2
Reputation: 15
Just try using URL constructor
const validateIPAddress = (ipAddress) => {
try {
new URL(`http://${ipAddress}`);
return true;
} catch (error) {
alert("Wrong IP Address");
return false;
}
}
Upvotes: 0
Reputation: 4233
don't reinvent the wheel ;)
the best way is to use well written and tested library
npm @sideway/address
has 6M weekly downloads
import { ipRegex } from "@sideway/address";
const { regex } = ipRegex({ version: ['ipv4'], cidr: 'forbidden' });
the regex for ipv4 without cidr is:
/^(?:(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))$/
unit tested on:
const validIPv4sWithoutCidr = [
'0.0.0.0',
'255.255.255.255',
'127.0.0.1',
'192.168.2.1',
'0.0.0.3',
'0.0.0.7',
'0.0.0.15',
'0.0.0.31',
'0.0.0.63',
'0.0.0.127',
'01.020.030.100',
'0.0.0.0',
'00.00.00.00',
'000.000.000.000'
];
but you can easily with (without) options match other versions and be sure it covers all possibilities
import { ipRegex } from "@sideway/address";
const { regex } = ipRegex();
/^(?:(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?:\/(?:\d|[1-2]\d|3[0-2]))?|(?:(?:[\dA-Fa-f]{1,4}:){6}(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|::(?:[\dA-Fa-f]{1,4}:){5}(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:[\dA-Fa-f]{1,4})?::(?:[\dA-Fa-f]{1,4}:){4}(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:[\dA-Fa-f]{1,4}:){0,1}[\dA-Fa-f]{1,4})?::(?:[\dA-Fa-f]{1,4}:){3}(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:[\dA-Fa-f]{1,4}:){0,2}[\dA-Fa-f]{1,4})?::(?:[\dA-Fa-f]{1,4}:){2}(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:[\dA-Fa-f]{1,4}:){0,3}[\dA-Fa-f]{1,4})?::[\dA-Fa-f]{1,4}:(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:[\dA-Fa-f]{1,4}:){0,4}[\dA-Fa-f]{1,4})?::(?:[\dA-Fa-f]{1,4}:[\dA-Fa-f]{1,4}|(?:(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:0{0,2}\d|0?[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|(?:(?:[\dA-Fa-f]{1,4}:){0,5}[\dA-Fa-f]{1,4})?::[\dA-Fa-f]{1,4}|(?:(?:[\dA-Fa-f]{1,4}:){0,6}[\dA-Fa-f]{1,4})?::)(?:\/(?:0{0,2}\d|0?[1-9]\d|1[01]\d|12[0-8]))?|v[\dA-Fa-f]+\.[\w-\.~!\$&'\(\)\*\+,;=:]+(?:\/(?:0{0,2}\d|0?[1-9]\d|1[01]\d|12[0-8]))?)$/
Upvotes: 1
Reputation: 1
-bash-3.2$ echo "191.191.191.39" | egrep
'(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
(2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'
>> 191.191.191.39
(This is a DFA that matches the entire addr space (including broadcasts, etc.) and nothing else.
Upvotes: 0
Reputation: 1555
Considering some variants suggested, \d
and \b
may not be supported. Hence, just in case:
^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)$
Test: https://debuggex.com/r/izHiog3KkYztRMSJ
Upvotes: 2
Reputation: 3630
Best for Now (43 chars)
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$
This version shortens things by another 6 characters while not making use of the negative lookahead, which is not supported in some regex flavors.
Newest, Shortest, Least Readable Version (49 chars)
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$
The [0-9]
blocks can be substituted by \d
in 2 places - makes it a bit less readable, but definitely shorter.
Even Newer, even Shorter, Second least readable version (55 chars)
^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
This version looks for the 250-5 case, after that it cleverly ORs all the possible cases for 200-249
100-199
10-99
cases. Notice that the |)
part is not a mistake, but actually ORs the last case for the 0-9 range. I've also omitted the ?:
non-capturing group part as we don't really care about the captured items, they would not be captured either way if we didn't have a full-match in the first place.
Old and shorter version (less readable) (63 chars)
^(?:(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(?!$)|$)){4}$
Older (readable) version (70 chars)
^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$
It uses the negative lookahead (?!)
to remove the case where the ip might end with a .
Alternative answer, using some of the newer techniques (71 chars)
^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$
Useful in regex implementations where lookaheads are not supported
Oldest answer (115 chars)
^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}
(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$
I think this is the most accurate and strict regex, it doesn't accept things like 000.021.01.0.
it seems like most other answers here do and require additional regex to reject cases similar to that one - i.e. 0
starting numbers and an ip that ends with a .
Upvotes: 268
Reputation: 323
I have a regexp, that match (extract) valid ip addresses from strings in text files.
\b(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b
\b
word boundary(?:
- means start non capturing group^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)
- string must start with first right octet with dot char
[1-9]
) - find first right octet - (firt octet can not start with - 0)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}
- find next right two octets with dot string(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\b
- string must end with right fourth octet (now zero char is allowed)But this ip regexp has a minority false positive matches:
Find or extract valid ip address from text file with only regexp is impossible. Without checking another conditions you always get false positive matches.
I write one liner perl for extract ip addresses from text files. It has this conditions:
The consequence is that perl not match strings like https://84.25.74.125
and another URI strings. Or ip addres at the end of line with dot char at the end. But it find any valid ip address in the text.
perl one liner solution:
$ cat ip.txt | perl -lane 'use warnings; use strict; for my $i (@F){if ($i =~/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/) { print $i; } }'
36.42.84.233
158.22.45.0
36.84.84.233
12.0.5.4
1.25.45.36
255.3.6.5
4.255.2.1
127.0.0.1
127.0.0.5
126.0.0.1
testing text file:
$ cat ip.txt
36.42.84.233 stop 158.22.45.0 and 56.32.58.2.
25.36.84.84abc and abc2.4.8.2 is error.
1.2.3.4_
But false positive is 2.2.2.2.2.2.2.2 or 1.1.1.1.1
http://23.54.212.1:80
https://89.35.248.1/abc
36.84.84.233 was 25.36.58.4/abc/xyz&158.133.26.4&another_var
and 42.27.0.1:8333 in http://212.158.45.2:26
0.25.14.15 ip can not start with zero
2.3.0
abc 12.0.5.4
1.25.45.36
12.05.2.5
256.1.2.5
255.3.6.5
4.255.2.1
4.256.5.6
127.0.0.1 is localhost.
this ip 127.0.0.5 is not localhost
126.0.0.1
For people from another planets for whom the strings 2130706433
, 127.1
, 24.005.04.52
is a valid ip address I have a message: Try to find a solution yourself!!!
Upvotes: 3
Reputation: 35
To validate any IP address in the valid range 0.0.0.0 to 255.255.255.255 can be written in very simple form as below.
((1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.){3}(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])
Upvotes: 1
Reputation: 21
My solution here:
^([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}$
This regex will match:
0.0.0.0
255.255.255.255
123.123.123.123
127.0.0.1
192.168.0.1
But it will NOT match:
192.168.1.01
256.256.256.256
01.01.01.01
Upvotes: 0
Reputation: 931
Here is a better one with passing/failing IPs attached
/^((?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])[.]){3}(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/
Accepts
127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
10.1.1.1
0.0.0.0
Rejects
1.1.1.01
30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3
192.168.1.099
Upvotes: 6
Reputation: 21
This pattern unclude 52 symbols and accept cuncks started with zero.
/^(?:(?:[01]?\d?\d|2[0-4]\d|25[0-5])(?:\.|$)){4}\b$/
Upvotes: 0
Reputation: 27738
IPv4 address (accurate capture) Matches 0.0.0.0 through 255.255.255.255, but does capture invalid addresses such as 1.1.000.1 Use this regex to match IP numbers with accuracy. Each of the 4 numbers is stored into a capturing group, so you can access them for further processing.
\b
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)
\b
taken from JGsoft RegexBuddy library
Edit: this (\.|$)
part seems weird
Upvotes: 16
Reputation: 3128
^((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]?)$
Accept:
127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01 # This is an invalid IP address!
Reject:
30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3
Try online with unit tests: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1
Upvotes: 119
Reputation: 247
My [extended] approach → regexp for space-separated IP addresses:
((((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?=\\d)|(?!\\d))){4})( (?!$)|$))+
Uses PCRE look-ahead.
Upvotes: 0
Reputation: 499
Valid regex for IPV4 address for Java
^((\\d|[1-9]\\d|[0-1]\\d{2}|2[0-4]\\d|25[0-5])[\\.]){3}(\\d|[1-9]\\d|[0-1]\\d{2}|2[0-4]\\d|25[0-5])$
Upvotes: 2
Reputation: 71
I tried to make it a bit simpler and shorter.
^(([01]?\d{1,2}|2[0-4]\d|25[0-5]).){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$
If you are looking for java/kotlin:
^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$
If someone wants to know how it works here is the explanation. It's really so simple. Just give it a try :p :
1. ^.....$: '^' is the starting and '$' is the ending.
2. (): These are called a group. You can think of like "if" condition groups.
3. |: 'Or' condition - as same as most of the programming languages.
4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.
5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.
6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.
7. \.: It's just plan '.'(dot) for separating the numbers.
8. {3}: It means the exact 3 repetition of the previous group inside '()'.
9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6
Mathematically it is like:
(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)
So, as you can see normally this is the pattern for the IP addresses. I hope it helps to understand Regular Expression a bit. :p
Upvotes: 1
Reputation: 71
I tried to make it a bit simpler and shorter.
^(([01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}([01]?\d{1,2}|2[0-4]\d|25[0-5])$
If you are looking for java/kotlin:
^(([01]?\\d{1,2}|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d{1,2}|2[0-4]\\d|25[0-5])$
If someone wants to know how it works here is the explanation. It's really so simple. Just give it a try :p :
1. ^.....$: '^' is the starting and '$' is the ending.
2. (): These are called a group. You can think of like "if" condition groups.
3. |: 'Or' condition - as same as most of the programming languages.
4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.
5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.
6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.
7. \.: It's just plan '.'(dot) for separating the numbers.
8. {3}: It means the exact 3 repetition of the previous group inside '()'.
9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6
Mathematically it is like:
(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)
So, as you can see normally this is the pattern for the IP addresses. I hope it helps to understand Regular Expression a bit. :p
Upvotes: 1
Reputation: 66
For number from 0 to 255 I use this regex:
(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))
Above regex will match integer number from 0 to 255, but not match 256.
So for IPv4 I use this regex:
^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})$
It is in this structure: ^(N)((\.(N)){3})$
where N is the regex used to match number from 0 to 255.
This regex will match IP like below:
0.0.0.0
192.168.1.2
but not those below:
10.1.0.256
1.2.3.
127.0.1-2.3
For IPv4 CIDR (Classless Inter-Domain Routing) I use this regex:
^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))$
It is in this structure: ^(N)((\.(N)){3})\/M$
where N is the regex used to match number from 0 to 255, and M is the regex used to match number from 0 to 32.
This regex will match CIDR like below:
0.0.0.0/0
192.168.1.2/32
but not those below:
10.1.0.256/16
1.2.3./24
127.0.0.1/33
And for list of IPv4 CIDR like "10.0.0.0/16", "192.168.1.1/32"
I use this regex:
^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$
It is in this structure: ^(“C”)((,([ ]*)(“C”))*)$
where C is the regex used to match CIDR (like 0.0.0.0/0).
This regex will match list of CIDR like below:
“10.0.0.0/16”,”192.168.1.2/32”, “1.2.3.4/32”
but not those below:
“10.0.0.0/16” 192.168.1.2/32 “1.2.3.4/32”
Maybe it might get shorter but for me it is easy to understand so fine by me.
Hope it helps!
Upvotes: 4
Reputation: 1
I saw very bad regexes in this page.. so i came with my own:
\b((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\b
Explanation:
num-group = (0-9|10-99|100-199|200-249|250-255)
<border> + { <num-group> + <dot-cahracter> }x3 + <num-group> + <border>
Here you can verify how it works here
Upvotes: 0
Reputation: 99
This one matches only valid IPs (no prepended 0's, but it will match octets from 0-255 regardless of their 'function' [ie reserved, private, etc]) and allows for inline matching, where there may be spaces before and/or after the IP, or when using CIDR notation.
grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)'
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.2'
10.0.1.2
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2'
ip address 10.0.1.2
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2 255.255.255.255'
ip address 10.0.1.2 255.255.255.255
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2/32'
ip address 10.0.1.2/32
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2.32'
$
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address10.0.1.2'
$
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.256'
$
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '0.0.0.0'
0.0.0.0
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.255'
255.255.255.255
$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.256'
$
Of course, in cases where the IP is inline, you can use grep option "-o" and your preference of whitespace trimmer if you just want the whole IP and nothing but the IP.
For those of us using python, the equivalent is roughly:
>>> ipv4_regex = re.compile(r'(^| )((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])($| |/)')
>>> ipv4_regex.search('ip address 10.1.2.3/32')
<re.Match object; span=(10, 20), match=' 10.1.2.3/'>
If you're picky (lazy) like me, you probably would prefer to use grouping to get the whole IP and nothing but the IP, or the CIDR and nothing but the CIDR or some combination thereof. We can use (?P) syntax to name our groups for easier reference.
>>> ipv4_regex = re.compile(r'(?:^| )(?P<address>((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]))(?P<slash>/)?(?(slash)(?P<cidr>[0-9]|[12][0-9]|3[0-2]))(?:$| )')
>>> match = ipv4_regex.search('ip address 10.0.1.2/32')
>>> match.group('address')
'10.0.1.2'
>>> match.group('cidr')
'32'
>>> "".join((match.group('address'), match.group('slash'), match.group('cidr')))
'10.0.1.2/32'
There's ways of not using just regex, of course. Here's some conditions that you could check (this one doesn't find inline, just validates the passed address is valid).
First check is that each char in the address is a digit or a '.'
Next checking that there are exactly 3 '.'
The next two checks check that each octet is between 0 and 255.
And the last check is that no octets are prepended with a '0'
def validate_ipv4_address(address):
return all(re.match('\.|\d', c) for c in address) \
and address.count('.') == 3 \
and all(0 <= int(octet) <= 255 for octet in address.split('.')) \
and all((len(bin(int(octet))) <= 10 for octet in address.split('.'))) \
and all(len(octet) == 1 or d[0] != '0' for octet in address.split('.'))
>>> validate_ipv4_address('255.255.255.255')
True
>>> validate_ipv4_address('10.0.0.1')
True
>>> validate_ipv4_address('01.01.01.01')
False
>>> validate_ipv4_address('123.456.789.0')
False
>>> validate_ipv4_address('0.0.0.0')
True
>>> validate_ipv4_address('-1.0.0.0')
False
>>> validate_ipv4_address('1.1.1.')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('.1.1.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('1..1.1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in validate_ipv4_address
File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
(bitwise, each octet should be 8 bits or less, but each is prepended with '0b')
>>> bin(0)
'0b0'
>>> len(bin(0))
3
>>> bin(255)
'0b11111111'
>>> len(bin(256))
11
Upvotes: 0
Reputation: 15472
I think many people reading this post will be looking for simpler regular expressions, even if they match some technically invalid IP addresses. (And, as noted elsewhere, regex probably isn't the right tool for properly validating an IP address anyway.)
Remove ^
and, where applicable, replace $
with \b
, if you don't want to match the beginning/end of the line.
Basic Regular Expression (BRE) (tested on GNU grep, GNU sed, and vim):
/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/
Extended Regular Expression (ERE):
/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/
or:
/^([0-9]+(\.|$)){4}/
Perl-compatible Regular Expression (PCRE) (tested on Perl 5.18):
/^\d+\.\d+\.\d+\.\d+$/
or:
/^(\d+(\.|$)){4}/
Ruby (tested on Ruby 2.1):
Although supposed to be PCRE, Ruby for whatever reason allowed this regex not allowed by Perl 5.18:
/^(\d+[\.$]){4}/
My tests for all these are online here.
Upvotes: 15
Reputation: 61
''' This code works for me, and is as simple as that.
Here I have taken the value of ip and I am trying to match it with regex.
ip="25.255.45.67"
op=re.match('(\d+).(\d+).(\d+).(\d+)',ip)
if ((int(op.group(1))<=255) and (int(op.group(2))<=255) and int(op.group(3))<=255) and (int(op.group(4))<=255)):
print("valid ip")
else:
print("Not valid")
Above condition checks if the value exceeds 255 for all the 4 octets then it is not a valid. But before applying the condition we have to convert them into integer since the value is in a string.
group(0) prints the matched output, Whereas group(1) prints the first matched value and here it is "25" and so on. '''
Upvotes: 6
Reputation: 81
Easy way
((25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]{0,1})\.){3}(25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]{0,1})
Upvotes: 0
Reputation: 39
Following is the regex expression to validate the IP-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]?)$
Upvotes: 0
Reputation: 61
Above answers are valid but what if the ip address is not at the end of line and is in between text.. This regex will even work on that.
code: '\b((([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]))\b'
input text file:
ip address 0.0.0.0 asfasf
sad sa 255.255.255.255 cvjnzx
zxckjzbxk 999.999.999.999 jshbczxcbx
sjaasbfj 192.168.0.1 asdkjaksb
oyo 123241.24121.1234.3423 yo
yo 0000.0000.0000.0000 y
aw1a.21asd2.21ad.21d2
yo 254.254.254.254 y0
172.24.1.210 asfjas
200.200.200.200
000.000.000.000
007.08.09.210
010.10.30.110
output text:
0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200
Upvotes: 5
Reputation: 454
ip address can be from 0.0.0.0 to 255.255.255.255
(((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])[.]){3}((0|1)?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$
(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character
{3} --> will match exactly 3
$ --> end of string
Upvotes: 0