Pwnna
Pwnna

Reputation: 9538

PHP preg_match problem with IPv6

I'm matching for ip addresses in PHP. So my check is:

function checkIP($ip){
    $ip = trim($ip);
    if (preg_match("\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", $ip)) return true;
    $v6pattern = "/
(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,6}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,5}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,4}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,3}\Z)|
(\A([0-9a-f]{1,4}:){1,5}(:[0-9a-f]{1,4}){1,2}\Z)|
(\A([0-9a-f]{1,4}:){1,6}(:[0-9a-f]{1,4}){1,1}\Z)|
(\A(([0-9a-f]{1,4}:){1,7}|:):\Z)|
(\A:(:[0-9a-f]{1,4}){1,7}\Z)|
(\A((([0-9a-f]{1,4}:){6})(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A(([0-9a-f]{1,4}:){5}[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3})\Z)|
(\A([0-9a-f]{1,4}:){5}:[0-9a-f]{1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,1}(:[0-9a-f]{1,4}){1,4}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,2}(:[0-9a-f]{1,4}){1,3}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,3}(:[0-9a-f]{1,4}){1,2}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A([0-9a-f]{1,4}:){1,4}(:[0-9a-f]{1,4}){1,1}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A(([0-9a-f]{1,4}:){1,5}|:):(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)|
(\A:(:[0-9a-f]{1,4}){1,5}:(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\Z)
/x";
    if (preg_match($v6pattern, $ip)) return true;
    return false;
}

However, I'm getting an error: warning: preg_match() [function.preg-match]: Delimiter must not be alphanumeric or backslash in C:\xampp\htdocs\index.php on line 5

Line 5 is if (preg_match("\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", $ip)) return true;

What's wrong?

Upvotes: 2

Views: 2509

Answers (5)

Buddy
Buddy

Reputation: 1836

You have to place your regex between delimiters. Check Manual. You can also use filters and avoid reinventing the wheel. For example:

filter_var($var, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); //for IP's V6

and

filter_var($var, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); //for IP's V4

Upvotes: 6

Shahbaz
Shahbaz

Reputation: 334

To match an IPv4 address you can simply use:

preg_match("/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}/", $string, $result);

Upvotes: 0

Steve-o
Steve-o

Reputation: 12866

If you don't mind both IPv4 and IPv6 addresses it would be more convenient to feed through inet_ntop and inet_pton, e.g.

function is_ip($address) {
  $packed = inet_pton ($address);
  if (FALSE == $packed || FALSE === inet_ntop ($packed)) {
    return FALSE;
  }
  return TRUE;
}

Upvotes: 0

Byron Whitlock
Byron Whitlock

Reputation: 53921

I would skip the regex and use the validate module from zend. Much easier and robust than the regex you have posted.

  $validator = new Zend_Validate_Ip();

  if ($validator->isValid($ip)) {

      // ip appears to be valid

  } else {

      // ip is invalid; print the reasons

  }

Upvotes: 5

codaddict
codaddict

Reputation: 455380

Your first call to preg_match does not have a delimiter for the regex used.

PHP expects the regex in preg_match to be enclosed between a pair of delimiters. The character / is popular choice of delimiter which is also used in your 2nd call to preg_match. You can also use characters like #, |, @, ~, !.

Add the missing delimier as:

if (preg_match("#\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#", $ip)) return true;
                ^                                                                                                                                                                  ^

Upvotes: 2

Related Questions