我的数据来自数据库(非常受控的输入),在它们之前和之后会有下划线。它们存储如下:
_51_ _356_
它们不会以任何其他格式存储,但有时我需要从中获取数字。我选择使用
$x = filter_var($myNumber, FILTER_SANITIZE_NUMBER_INT);
或
$y = preg_replace("/[^0-9]/","",$myNumber);
我不确定后端2中的细微差别,但它们都产生了我需要的东西(我想是的,无论如何),所以对我来说并不重要。使用这些选项有哪些优缺点? (例如,是否有人使用我可能需要知道的数组或其他奇怪的东西?一个使用太多资源的方式?)
答案 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;