Какой самый быстрый способ проверить количество определенных символов в строке в PHP?

Так что мне нужно проверить, если количество символов из определенного набора в строке больше, чем какое-то число, какой самый быстрый способ сделать это?

Например, у меня есть длинная строка " некоторый текст и некоторый текст и некоторый текст + намного больше + намного больше… и т. Д. ", И мне нужно проверить, есть ли более 3 следующих символов: [ &,., + ]. Поэтому, когда я сталкиваюсь с 4-м появлением одного из этих символов, мне просто нужно вернуть false и остановить цикл. Поэтому я думаю создать такую ​​простую функцию. Но мне интересно, есть ли какой-нибудь нативный метод в php, чтобы сделать такую ​​вещь? Но мне нужна функция, которая не будет тратить время на разбор строки до конца, потому что строка может быть довольно длинной. Так что я думаю, что регулярные выражения и функции, такие как count_chars, не подходят для такой работы...

Какие-либо предложения?

3 ответа

Решение

Ну, все мои мысли были неправильными, и мои ожидания были разрушены реальными испытаниями. RegExp работает в 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);
}

PS Я не удосужился проверить время процессора, просто тестировал время на стене, измеренное с помощью микротайма (правда); цикла итерации 200К, но мне этого достаточно.

Я не знаю о родном методе, я думаю 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 2-й параметр, чтобы прочитать только количество байтов за раз в пределах while петля.

Поиск самого быстрого пути может быть слишком широким вопросом, так как PHP имеет много функций, связанных со строками; другие решения могут использовать strstr, strpos, так далее...

Не сравнивать с другими решениями, но http://php.net/manual/en/function.str-replace.php передать множество параметров будет быстро. Существует необязательный параметр, который возвращает количество замен. Проверьте это число

 str_replace ( ['&','.','+'], '' , $subject , $count  )

 if ($count > $number ) {
Другие вопросы по тегам