Php 试图计算变量内部的数字

Php 试图计算变量内部的数字,php,regex,Php,Regex,我试图计算一个变量中有多少个数字。这是我使用的正则表达式 preg_match('/[^0-9]/', $password, $numbers, PREG_OFFSET_CAPTURE); 当我试图逐一获取所有数字时,我使用: print_r($this->filter->password_filter($data["user_password"])); 用户密码为123d4sd6789。结果是一个空数组 Array ( ) 好的,您可以使用preg\u split轻松完成:

我试图计算一个变量中有多少个数字。这是我使用的正则表达式

preg_match('/[^0-9]/', $password, $numbers, PREG_OFFSET_CAPTURE);
当我试图逐一获取所有数字时,我使用:

print_r($this->filter->password_filter($data["user_password"]));
用户密码为123d4sd6789。结果是一个空数组

Array ( )

好的,您可以使用
preg\u split
轻松完成:

$temp = preg_split('/\d/', $password);
$numCount = count($temp) - 1;
您的正则表达式有缺陷,因为您试图使用以下方法计算密码中的位数:

/[^0-9]/
不会删掉的,也许你想写:

/[0-9]/
因为你现在拥有的一切都匹配,除了一个数字

有很多方法可以实现您想要实现的目标,我已经对4种不同的方法进行了基准测试,发现使用regex是最快的方法。使用PHP附带的捆绑式pcre扩展,
preg_split
在70%的时间、20%的时间内优于所有其他方法,但循环速度更快,~10%的
preg_match_all
速度最快。
在codepad上,由于某种原因没有使用标准PCRE,
preg\u match\u all
不起作用,
shuffle
也没有被证明是可靠的,所以我添加了一个
knuth
方法,我决定将
/\d/
/[0-9]/
preg\u split
结合起来测试两者之间的差异。因此,在代码板上,正则表达式的速度超过95%。
简而言之:使用
preg_split
+regex可获得最佳结果

无论如何,这里是基准代码。将所有内容都放在一个类中似乎很愚蠢,但实际上,这是一种公平的基准测试方法。处理的字符串和用于对函数计时和比较速度的所有数组都保存在内存中。
我也不是直接调用测试方法,而是使用
timeCall
方法,因为我希望垃圾收集器在每次调用后对需要GC的内容进行GC。不管怎样,理解这段代码并不难,重要的是结果

class Bench
{
    /**
     * @var string
     */
    private $str = '123d4sd6789';

    private $functions = array(
        'regex' => null,
        'regex2' => null,
        'loop' => null,
        'loop2' => null
    );

    private $random = null;

    public function __construct()
    {
        $this->random = array_keys($this->functions);
        if (!shuffle($this->random)) $this->knuth();
    }

    /**
     * Knuth shuffle
     */
    private function knuth()
    {
        for ($i=count($this->random)-1,$j=mt_rand(0,$i);$i>0;$j=mt_rand(0,--$i))
        {
            $temp = $this->random[$j];
            $this->random[$j] = $this->random[$i];
            $this->random[$i] = $temp;
        }
    }

    /**
     * Call all functions in random order, timing each function
     * determine fastest approach, and echo results
     * @param $randomize
     * @return string
     */
    public function test($randomize)
    {
        if ($randomize) if (!shuffle($this->random)) $this->knuth();
        foreach($this->random as $func) $this->functions[$func] = $this->timeCall($func);
        $fastest = array('f', 100000);
        foreach($this->functions as $func => $time)
        {
            $fastest = $fastest[1] > $time ? array($func, $time) : $fastest;
            echo 'Function ', $func, ' took ', $time, 'ms', PHP_EOL;
        }
        echo 'Fastest approach: ', $fastest[0], ' (', $fastest[1], 'ms)', PHP_EOL;
        return $fastest[0];
    }

    /**
     * Time function call
     * @param string $func
     * @return float mixed
     */
    private function timeCall($func)
    {
        echo $func, PHP_EOL;
        $start = microtime(true);
        $this->{$func}();
        return (microtime(true) - $start);
    }

    /**
     * Count digits in string using preg_split
     * @return int
     */
    private function regex()
    {
        return count(preg_split('/\d/', $this->str)) - 1;
    }

    /**
     * count digits in string using str_split + is_numeric + loop
     * @return int
     */
    private function loop()
    {
        $chars = str_split($this->str);
        $counter = 0;
        foreach($chars as $char) if (is_numeric($char)) ++$counter;
        return $counter;
    }

    /**
     * count digits by iterating over string, using is_numeric
     * @return int
     */
    private function loop2()
    {
        for($i=0,$j=strlen($this->str),$counter=0;$i<$j;++$i) if (is_numeric($this->str{$i})) ++$counter;
        return $counter;
    }

    /**
     * use preg_split + [0-9] instead of \d
     * @return int
     */
    private function regex2()
    {
        return count(preg_split('/[0-9]/', $this->str)) - 1;
        if (preg_match_all('/[0-9]/',$this->str, $matches)) return count($matches);
        return 0;
    }

}


$benchmark = new Bench();
$totals = array();
for($i=0;$i<10;++$i)
{
    $func = $benchmark->test($i);
    if (!isset($totals[$func])) $totals[$func] = 0;
    ++$totals[$func];
    if ($i < 9) echo PHP_EOL, '---------------------------------------------', PHP_EOL;
}
var_dump($totals);
class-Bench
{
/**
*@var字符串
*/
私人$str='123d4sd6789';
私有$functions=array(
'regex'=>null,
“regex2”=>null,
“循环”=>null,
“loop2”=>null
);
private$random=null;
公共函数构造()
{
$this->random=array\u key($this->functions);
如果(!shuffle($this->random))$this->knuth();
}
/**
*克努斯洗牌
*/
私有函数knuth()
{
对于($i=count($this->random)-1,$j=mt_rand(0,$i);$i>0;$j=mt_rand(0,-$i))
{
$temp=$this->random[$j];
$this->random[$j]=$this->random[$i];
$this->random[$i]=$temp;
}
}
/**
*以随机顺序调用所有函数,对每个函数计时
*确定最快的方法和回显结果
*@param$randomize
*@返回字符串
*/
公共功能测试(随机)
{
if($randomize)if(!shuffle($this->random))$this->knuth();
foreach($this->random as$func)$this->functions[$func]=$this->timeCall($func);
$faster=阵列('f',100000);
foreach($this->函数为$func=>$time)
{
$faster=$faster[1]>$time?数组($func,$time):$faster;
echo'Function',$func','take',$time',ms',PHP_EOL;
}
echo'faster approach:'、$faster[0]、'('、$faster[1]、'ms')、PHP_EOL;
返回$faster[0];
}
/**
*时间函数调用
*@param字符串$func
*@返回浮动混合
*/
私有函数timeCall($func)
{
echo$func,PHP\u EOL;
$start=microtime(真);
$this->{$func}();
返回值(微时间(真)-$start);
}
/**
*使用preg_split对字符串中的数字进行计数
*@return int
*/
私有函数regex()
{
返回计数(预分割('/\d/',$this->str))-1;
}
/**
*使用str\u split+is\u numeric+循环计算字符串中的数字
*@return int
*/
私有函数循环()
{
$chars=str\u split($this->str);
$counter=0;
foreach($chars作为$char)if(是数值($char))+$counter;
返回$count;
}
/**
*通过在字符串上迭代来计算数字,使用is_numeric
*@return int
*/
私有函数loop2()
{
对于($i=0,$j=strlen($this->str),$counter=0;$istr{$i}))+$counter;
返回$count;
}
/**
*使用preg_split+[0-9]而不是\d
*@return int
*/
私有函数regex2()
{
返回计数(预分割('/[0-9]/',$this->str))-1;
if(preg_match_all('/[0-9]/',$this->str,$matches))返回计数($matches);
返回0;
}
}
$benchmark=新工作台();
$totals=array();
对于($i=0;$i测试($i);
如果(!isset($totals[$func]))$totals[$func]=0;
++$totals[$func];
如果($i<9)回显PHP_EOL,“-------------------------------------------------------------”,PHP_EOL;
}
var_dump(总计);

你真的想要一个正则表达式吗

$arr1 = str_split($password);
$counter=0;
foreach($arr1 as $v){
  if(is_numeric($v))$counter++;
}

使用
preg\u match\u all
选择所有数字:

$reg = '/[0-9]/';
$string = '123d4sd6789';

preg_match_all($reg, $string, $out);
echo (count($out[0]));

当我使用/[0-9]/result:“Array([0]=>Array([0]=>1[1]=>0))”@Yusuf:你是如何将
/[0-9]/
preg\u match
一起使用的?因为我使用的是
preg\u split
count
结果数组的大小(-1),当应用于
123d4sd6789
时,它给出了预期的结果:8但它返回1。因为数组中有一个数组。这就是我添加
[0]
的原因。下面是一个演示它是如何工作的(选择preg\u match\u all选项卡)@Yusuf:你可能想查看我更新的答案,我已经添加了一些关于如何做你想做的事情的各种方法的详细信息+做了一些基准测试好了,OP可能想在这里使用正则表达式,因为你的方法实际上比较慢:你在构造一个数组,然后将每个字符分配给
$v
,然后调用
是数字的n这个变量。太多了。我做了一些基准测试,并添加了基准脚本