我正在计算一个变量中有多少个数字。这是我使用的正则表达式..
preg_match('/[^0-9]/', $password, $numbers, PREG_OFFSET_CAPTURE);
当我尝试逐个获取所有数字时,我使用:
print_r($this->filter->password_filter($data["user_password"]));
user_password是123d4sd6789。结果是一个空数组。
Array ( )
答案 0 :(得分:2)
嗯,您可以使用preg_split
轻松完成:
$temp = preg_split('/\d/', $password);
$numCount = count($temp) - 1;
您的正则表达式存在缺陷,因为您尝试使用以下方法计算密码中的位数:
/[^0-9]/
不会削减它,你想要写下来:
/[0-9]/
因为您现在所拥有的内容所有内容除了一个数字。
有很多方法可以做你想要做的事情,我已经对4种不同的方法进行了基准测试,发现使用正则表达式是最快的方法。使用PHP附带的捆绑pcre扩展,preg_split
优于所有其他方法~70%的时间,20%的时间,循环更快,而且~10%preg_match_all
最快。
在键盘上,由于某种原因,谁不使用标准PCRE,preg_match_all
不起作用,shuffle
也不可靠,所以我添加了knuth
方法,我决定将/\d/
和/[0-9]/
之间的差异与preg_split
结合使用。在键盘上,正则表达式的结果更快> 95%
简而言之:使用preg_split
+正则表达式获得最佳效果。
无论如何,这是基准代码。将它全部放入课堂似乎很愚蠢,但实际上,这是公平的基准测试方式。处理的字符串保存在内存中,用于计时功能的所有数组也都保存在内存中,并比较速度
我也没有直接调用测试方法,而是使用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);
答案 1 :(得分:0)
你真的想要正则表达式吗?
$arr1 = str_split($password);
$counter=0;
foreach($arr1 as $v){
if(is_numeric($v))$counter++;
}
答案 2 :(得分:0)
使用preg_match_all
选择所有数字:
$reg = '/[0-9]/';
$string = '123d4sd6789';
preg_match_all($reg, $string, $out);
echo (count($out[0]));