检查 PHP 中字符串中特定字符数量的最快方法是什么?
What is the fastest way to check amount of specific chars in a string in PHP?
所以我需要检查字符串中特定集合的字符数量是否高于某个数字,最快的方法是什么?
例如我有一个长字符串“some text & some text & some text + a lot more + a lot more ... etc.”我需要检查如果下一个符号超过 3 个:[&,。,+]。因此,当我遇到这些字符之一的第 4 次出现时,我只需要 return false,并停止循环。所以我想创建一个像这样的简单函数。但我想知道 php 中是否有任何本地方法可以做这样的事情?但是我需要一些不会浪费时间解析字符串直到最后的函数,因为字符串可能很长。所以我认为正则表达式和函数 count_chars r 不适合那种工作...
有什么建议吗?
我不知道 native 方法,我认为 count_chars
可能与您将要获得的一样接近。但是,滚动自定义解决方案会相对简单:
$str = 'your text here';
$chars = ['&', '.', '+'];
$count = [];
$length = strlen($str);
$limit = 3;
for ($i = 0; $i < $length; $i++) {
if (in_array($str[$i], $chars)) {
$count[$str[$i]] += 1;
if ($count[$str[$i]] > $limit) {
break;
}
}
}
数据的实际来源可能也会有所不同。例如,如果它来自文件,那么您可以利用 fread
的第二个参数在 while
循环中一次只读取 x 个字节。
找到最快的方法可能是一个太宽泛的问题,因为PHP有很多与字符串相关的函数;其他解决方案可能使用 strstr
, strpos
,等等...
好吧,我所有的想法都是错误的,我的期望被真实的测试击碎了。 RegExp 似乎比使用简单 symbol-checking 循环的 self-made 函数快 2 到 7 倍(使用不同的字符串)。
代码:
// self-made function:
function chk_occurs($str,$chrs,$limit){
$r=false;
$count = 0;
$length = strlen($str);
for($i=0; $i<$length; $i++){
if(in_array($str[$i], $chrs)){
$count++;
if($count>$limit){
$r=true;
break;
}
}
}
return $r;
}
// RegExp i've used for tests:
preg_match('/([&\.\+]|[&\.\+][^&\.\+]+?){3,}?/',$str);
当然,它的运行速度更快,因为它是对本机函数的单次调用,但即使是包装到函数中的相同代码,运行速度也要快 2 到 ~4.8 倍。
//RegExp wrapped into the function:
function chk_occurs_preg($str,$chrs,$limit){
$chrs=preg_quote($chrs);
return preg_match('/(['.$chrs.']|['.$chrs.'][^'.$chrs.']+?){'.$limit.',}?/',$str);
}
P.S。我懒得检查 cpu-time,只是测试通过 200k 迭代循环的 microtime(true); 测量的 walltime,但这对我来说已经足够了。
未对其他解决方案进行基准测试,但 http://php.net/manual/en/function.str-replace.php 传递一组选项会很快。有一个可选参数 returns 替换次数。检查那个数字
str_replace ( ['&','.','+'], '' , $subject , $count )
if ($count > $number ) {
所以我需要检查字符串中特定集合的字符数量是否高于某个数字,最快的方法是什么?
例如我有一个长字符串“some text & some text & some text + a lot more + a lot more ... etc.”我需要检查如果下一个符号超过 3 个:[&,。,+]。因此,当我遇到这些字符之一的第 4 次出现时,我只需要 return false,并停止循环。所以我想创建一个像这样的简单函数。但我想知道 php 中是否有任何本地方法可以做这样的事情?但是我需要一些不会浪费时间解析字符串直到最后的函数,因为字符串可能很长。所以我认为正则表达式和函数 count_chars r 不适合那种工作...
有什么建议吗?
我不知道 native 方法,我认为 count_chars
可能与您将要获得的一样接近。但是,滚动自定义解决方案会相对简单:
$str = 'your text here';
$chars = ['&', '.', '+'];
$count = [];
$length = strlen($str);
$limit = 3;
for ($i = 0; $i < $length; $i++) {
if (in_array($str[$i], $chars)) {
$count[$str[$i]] += 1;
if ($count[$str[$i]] > $limit) {
break;
}
}
}
数据的实际来源可能也会有所不同。例如,如果它来自文件,那么您可以利用 fread
的第二个参数在 while
循环中一次只读取 x 个字节。
找到最快的方法可能是一个太宽泛的问题,因为PHP有很多与字符串相关的函数;其他解决方案可能使用 strstr
, strpos
,等等...
好吧,我所有的想法都是错误的,我的期望被真实的测试击碎了。 RegExp 似乎比使用简单 symbol-checking 循环的 self-made 函数快 2 到 7 倍(使用不同的字符串)。
代码:
// self-made function:
function chk_occurs($str,$chrs,$limit){
$r=false;
$count = 0;
$length = strlen($str);
for($i=0; $i<$length; $i++){
if(in_array($str[$i], $chrs)){
$count++;
if($count>$limit){
$r=true;
break;
}
}
}
return $r;
}
// RegExp i've used for tests:
preg_match('/([&\.\+]|[&\.\+][^&\.\+]+?){3,}?/',$str);
当然,它的运行速度更快,因为它是对本机函数的单次调用,但即使是包装到函数中的相同代码,运行速度也要快 2 到 ~4.8 倍。
//RegExp wrapped into the function:
function chk_occurs_preg($str,$chrs,$limit){
$chrs=preg_quote($chrs);
return preg_match('/(['.$chrs.']|['.$chrs.'][^'.$chrs.']+?){'.$limit.',}?/',$str);
}
P.S。我懒得检查 cpu-time,只是测试通过 200k 迭代循环的 microtime(true); 测量的 walltime,但这对我来说已经足够了。
未对其他解决方案进行基准测试,但 http://php.net/manual/en/function.str-replace.php 传递一组选项会很快。有一个可选参数 returns 替换次数。检查那个数字
str_replace ( ['&','.','+'], '' , $subject , $count )
if ($count > $number ) {