【问题标题】:PHP preg_match problem with IPv6IPv6的PHP preg_match问题
【发布时间】:2011-05-18 17:20:38
【问题描述】:

我正在匹配 PHP 中的 IP 地址。所以我的支票是:

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;
}

但是,我收到一个错误:warning: preg_match() [function.preg-match]: Delimiter must not be alphanumeric or backslash in C:\xampp\htdocs\index.php on line 5

第 5 行是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;

怎么了?

【问题讨论】:

  • 天哪,这是一个用于验证 IP 地址的大型正则表达式!你确定它需要那么复杂吗?
  • 正则表达式并不适合某些东西
  • 明白。相应地删除了我的评论。

标签: php regex ipv6


【解决方案1】:

您对preg_match 的第一次调用没有使用的正则表达式的分隔符。

PHP 期望 preg_match 中的正则表达式包含在一对分隔符之间。字符/ 是常用的分隔符选择,它也用于您对preg_match 的第二次调用。您还可以使用#|@~! 等字符。

将缺少的分隔符添加为:

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;
                ^                                                                                                                                                                  ^

【讨论】:

    【解决方案2】:

    我会跳过正则表达式并使用 zend 的 validate 模块。比您发布的正则表达式更简单、更强大。

      $validator = new Zend_Validate_Ip();
    
      if ($validator->isValid($ip)) {
    
          // ip appears to be valid
    
      } else {
    
          // ip is invalid; print the reasons
    
      }
    

    【讨论】:

      【解决方案3】:

      您必须将正则表达式放在分隔符之间。检查Manual。您也可以使用filters 并避免重新发明轮子。例如:

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

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

      【讨论】:

        【解决方案4】:

        如果您不介意 IPv4 和 IPv6 地址,则通过inet_ntopinet_pton 提供更方便,例如

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

        【讨论】:

          【解决方案5】:

          要匹配 IPv4 地址,您只需使用:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多