47

I am newbie with regex and I want to use preg_match function to find if a string is an IP address.

For example,

$string = "10.0.0.1";
preg_match($regex, $string);

should return true. So, what $regex should be?

ibrahim
  • 3,254
  • 7
  • 42
  • 56
  • 3
    Did you give a try to Google first? http://www.regular-expressions.info/regexbuddy/ipaccurate.html – Oscar Mederos May 03 '11 at 06:28
  • 4
    `45.56.78.888` is not an IP address. – kapa May 03 '11 at 06:39
  • @bazmegakapa yeah I just realize, I wrote it randomly:D but you got the point I think;) – ibrahim May 03 '11 at 06:54
  • possible duplicate of [Regular expression to match hostname or IP Address?](http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address) – rds Oct 23 '13 at 09:14
  • [Validating IPv4 addresses with regexp](https://stackoverflow.com/q/5284147/608639) – jww Nov 12 '18 at 09:19

3 Answers3

129

Don't use a regex when you don't need to :)

$valid = filter_var($string, FILTER_VALIDATE_IP);

Though if you really do want a regex...

$valid = preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/', $string);

The regex however will only validate the format, the max for any octet is the max for an unsigned byte, or 255.

This is why IPv6 is necessary - an IPv4 address is only 32bits long and the internet is popular :)

alex
  • 479,566
  • 201
  • 878
  • 984
  • 1
    Does filter_var work for ::1 as IP? –  Jun 03 '14 at 10:11
  • 2
    for good IP regex > http://stackoverflow.com/questions/9165922/regex-for-ip-address/20270082#20270082 – Alban Jul 28 '14 at 16:15
  • \b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b – Alex Jan 10 '15 at 09:00
  • 2
    Or `$valid = (filter_var($string, FILTER_VALIDATE_IP) !== false);` if you strictly want a boolean back. – Andy Fleming Oct 15 '15 at 02:43
  • @DesignerGuy Just prefixing it with `(bool)` would be better I reckon. – alex Oct 15 '15 at 03:28
  • @alex — True. Especially in this case it's probably fine. You'd only have to be careful in a variation of something like this where you could end up with a value that passes the filter but is still false-y. – Andy Fleming Oct 15 '15 at 17:22
  • @DesignerGuy It's been a while since I wrote some PHP, but if it returns a string, isn't the empty string the only false-y value? I wonder if that is ever a *valid match*. – alex Oct 15 '15 at 22:48
  • @alex — The string `'0'` will be treated as false. – Andy Fleming Oct 15 '15 at 23:13
  • @alex : Then 999.999.999.999 will also be valid IP then!!?? – Pratik Joshi Dec 08 '15 at 17:57
  • That is fairly simple but noone would want Wrong IP address. Please consider adding valid IP address Regex too as the answer. See people come on this page considering they would get Regex for **Valid** IP address, but they dont get that Regex. Thanks – Pratik Joshi Dec 08 '15 at 18:40
  • @PratikCJoshi At the expense of a complicated regex. You would be best to take each part as a matched group and validate its range then. – alex Dec 09 '15 at 08:43
  • Please edit the answer and explain as it would make sense. – Pratik Joshi Dec 09 '15 at 12:23
  • @PratikCJoshi it's already there – alex Dec 09 '15 at 13:19
  • Where is 255 limit in regex? – Pratik Joshi Dec 09 '15 at 16:30
  • @PratikCJoshi The answer is given in PHP, to use ´filter_var()´. How would sample code in PHP validating the parts make sense? I'm sure people don't have a problem implementing the condition ´$num <= 255´. – alex Dec 10 '15 at 08:56
  • better: /^(\d{1,3}\.){3}\d{1,3}$/ – ollazarev Jan 26 '16 at 11:24
  • @ollazarev Nice one, I don't know why that repetition in my regex didn't trigger my *there must be a better way* refactoring. – alex Jan 26 '16 at 12:31
9
/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/

should do for your example (which does contain a string that is not an IP address). And of course, it's only an IPv4 address.

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • @alex : Then 999.999.999.999 will also be valid IP then!!?? – Pratik Joshi Dec 08 '15 at 17:57
  • @PratikCJoshi: The original question (which has been edited years after my answer) asked for a regex that would match any sequence of four dot-separated numbers of up to 3 characters each... – Tim Pietzcker Dec 08 '15 at 18:25
  • 1
    That is fairly simple but noone would want Wrong IP address. Please consider adding valid IP address Regex too as the answer. See people come on this page considering they would get Regex for **Valid** IP address, but they dont get that Regex. Thanks – Pratik Joshi Dec 08 '15 at 18:29
7
/^(?:(?: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]?)$/ 

This will check for the Perfect Range including if a Range is Higher than 255 from any of 4.

JackSparrow
  • 948
  • 1
  • 11
  • 9