Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating IPv4 addresses with regexp

People also ask

What would be the regex to validate the IP address?

// Regex for digit from 0 to 255. // followed by a dot, repeat 4 times. // this is the regex to validate an IP address. = zeroTo255 + "\\."

How do I validate RegExp?

To validate a RegExp just run it against null (no need to know the data you want to test against upfront). If it returns explicit false ( === false ), it's broken. Otherwise it's valid though it need not match anything.


You've already got a working answer but just in case you are curious what was wrong with your original approach, the answer is that you need parentheses around your alternation otherwise the (\.|$) is only required if the number is less than 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\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]?)$

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


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 .

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 .


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


I was in search of something similar for IPv4 addresses - a regex that also stopped commonly used private ip addresses from being validated (192.168.x.y, 10.x.y.z, 172.16.x.y) so used negative look aheads to accomplish this:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(These should be on one line of course, formatted for readability purposes on 3 separate lines) Regular expression visualization

Debuggex Demo

It may not be optimised for speed, but works well when only looking for 'real' internet addresses.

Things that will (and should) fail:

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

IPs that will (and should) work:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

Provided in case anybody else is looking for validating 'Internet IP addresses not including the common private addresses'


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.