2006-11-16

Regular Expression To Match IPv4 Addresses

I needed a regex pattern to match IPv4 addresses today. I thought that this is quite common thing and it will be easy to find one on the Net. I have found a lot of them indeed. Unfortunately no one was good enough. Most of them was too simple and could match a string which is not IPv4 address. On the other hand, those more specific didn't match some fully legal IPv4 addresses (for example the one from regexlib.com). So I have developed my own:
((2[0-5]{2}|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(2[0-5]{2}|2[0-4]\d|1\d{2}|[1-9]\d|\d)
(/(3[012]|[12]\d|\d))?
This pattern matches all (I hope) IPv4 addresses in dot-decimal notation (first line) and network blocks in CIDR notation (when you join second line).

3 comments:

Anonymous said...

Thanks for the regex!

Anonymous said...

I made a small change....

see with regular IPv4 your regex matched an address like 400.123.34.56

but I liked your thinking... so I reversed your . and added the beginning marker.
^(25[0-5]|2[0-4]\d|[01]\d{2}|\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]\d{2}|\d{1,2})){3}$
^(25[0-5]|2[0-4]\d|[01]\d{2}|\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]\d{2}|\d{1,2})){3}(/(3[012]|[12]\d|\d))$

This seems to make sure that you don't have the one I mentioned above and/or one like 220.34.54.1000

(your regexp matched both of them.)

Hope this helps someone!

Shane said...

Thanks for the regex, it is good. It can be shortened very slightly:

((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)

Here we recognize that:

2[0-5]{2}

Can matches a lot of cases we don't care about, and simplify to:

25[0-5]

This approach was also taken in one of the comments. (I do not recommend the regex there, as it allows leading zeros in some cases.)

We also convert:

\d{2}

Into:

\d\d

This new regex is 6 characters shorter and matches an identical set. No idea about the performance. ;)