YiluPHP
这家伙很懒,什么都没有留下...

函数 实现PHP的sscanf()函数,解决自带sscanf()的BUG

2020年5月29日 浏览数 123138
函数名: str_sscanf
今天在使用PHP的sscanf()函数时,发现一个BUG,比如对比以下字符串和格式是否匹配,sscanf()函数是检测不出来的。

$str = 'jianli_file_12_34_56_78';
$format = 'jianli_file_%d_%s_%d_%d';
sscanf($str, $format, $res_1, $res_2, $res_3, $res_4);
 var_dump($res_1, $res_2, $res_3, $res_4);

//运行结果是:
int 12
string '34_56_78' (length=8)
null
null
PHP

sscanf()函数把第二个占位符以后的字符全部匹配完了,因为第二个位符是字符串类型的,它是贪婪模式的,不过如果我在第二个位符后面加一个空格就能正常运行了,但我的需求是不需要空格的,所以只能自己写了一个函数。

/**
     * 通过redis键名解析出与其对应的常量名
     * @param $str
     * @param $format
     * @return bool
     */
    function sscanf($str, $format)
    {
        $index = 0;
        $continue = 0;
        $length = strlen($format);
        $in_placer = false;
        for ($key=0; $key<$length; $key++){
            $value = $format[$key];
            if ($continue>0){
                $continue--;
                continue;
            }
            if ($value=='%' && isset($format[$key+1]) && in_array($format[$key+1], ['b','c','d','e','u','f','F','o','s','x','X'])){
                $in_placer = true;
                $continue = 1; //当次跳出,并且跳过一次
                $index++;
                continue;
            }

            while ($in_placer){
                if ($index>strlen($str) || !isset($format[$key+2])){
                    if ($index>strlen($str) && isset($format[$key+2])){
                        return false;
                    }
                    else if ($index>strlen($str) && !isset($format[$key+2])){
                        return true;
                    }
                    break;
                }
                if ($format[$key]==$str[$index]){
                    $in_placer = false;
                }
                else {
                    $index++;
                }
            }
            if ($continue>0){
                continue;
            }

            if ($value != $str[$index]){
                return false;
            }
            $index++;
        }
        return true;
    }
PHP

我写的这个函数没有仔细得区分各占位符的数据类型,不过这个不重要了,已经在基本的格式上达到要求了。

评论(0
还没有人评论哦
我来说说