" filter_var"之间的后端区别是什么?和" preg_replace"用PHP?

时间:2014-12-07 10:21:39

标签: php regex

我的数据来自数据库(非常受控的输入),在它们之前和之后会有下划线。它们存储如下:

_51_ _356_

它们不会以任何其他格式存储,但有时我需要从中获取数字。我选择使用

$x = filter_var($myNumber, FILTER_SANITIZE_NUMBER_INT);

$y = preg_replace("/[^0-9]/","",$myNumber);

我不确定后端2中的细微差别,但它们都产生了我需要的东西(我想是的,无论如何),所以对我来说并不重要。使用这些选项有哪些优缺点? (例如,是否有人使用我可能需要知道的数组或其他奇怪的东西?一个使用太多资源的方式?)

3 个答案:

答案 0 :(得分:2)

嗯,你的情况没有太大区别。我认为preg_replace资源更昂贵,因为它必须解析正则表达式模式。

或者,您可以使用trim

echo trim('_12_', '_');

它将删除双方的'_',我认为这是最易读的方式。

答案 1 :(得分:2)

过滤器不使用正则表达式,但工作方式类似:迭代字符串char-by-char并删除与模式不匹配的字符:

for (i = 0; i < Z_STRLEN_P(value); i++) {
    if ((*map)[str[i]]) {
        buf[c] = str[i];
        ++c;
    }
}

@ http://lxr.php.net/xref/PHP_5_6/ext/filter/sanitizing_filters.c#filter_map_apply

FILTER_SANITIZE_NUMBER_INT定义为[^0-9+-]

/* strip everything [^0-9+-] */
const unsigned char allowed_list[] = "+-" DIGIT;
filter_map     map;

filter_map_init(&map);
filter_map_update(&map, 1, allowed_list);
filter_map_apply(value, &map);

@ http://lxr.php.net/xref/PHP_5_6/ext/filter/sanitizing_filters.c#php_filter_number_int

当然,[^0-9+-]不是过滤整数的正确表达式,因此要为意外做好准备:

$x = filter_var("+++123---", FILTER_SANITIZE_NUMBER_INT);
var_dump($x); // WTF?

我的建议是坚持正则表达式:它们是明确的,远比过滤器少。

答案 2 :(得分:1)

我想尝试一些不同的方法,所以设置以下基准。它看起来像你的情况,修剪绝对是最好的选择,因为它只需要查看字符串的开头和结尾而不是每个字符。以下是10,000,000个随机整数的测试结果,其中包含运行PHP 7.0.18的下划线。

preg_replace:1.9469740390778秒。

filter_var:1.6922700405121秒。

str_replace:0.72129797935486秒。

修剪:0.37275195121765秒。

如果有人想要运行类似的测试,这是我的代码:

<?php
$ints = array();//array_fill(0, 10000000, '_1029384756_');
for($i = 0; $i < 10000000; $i++) {
$ints[] = '_'.mt_rand().'_';
}

$start = microtime(true);
foreach($ints as $v) {
preg_replace('/[^0-9]/', '', $v);
}
$end = microtime(true);
echo 'preg_replace in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
filter_var($v, FILTER_SANITIZE_NUMBER_INT);
}
$end = microtime(true);
echo 'filter_var in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
str_replace('_', '', $v);
}
$end = microtime(true);
echo 'str_replace in '.($end-$start).' seconds.',PHP_EOL;

$start = microtime(true);
foreach($ints as $v) {
trim($v, '_');
}
$end = microtime(true);
echo 'trim in '.($end-$start).' seconds.',PHP_EOL;