Допустим, у меня две строки.
$needle = 'AGUXYZ'; $haystack = 'Agriculture ID XYZ-A';
Я хочу подсчитать, как часто символы, которые находятся в $needle
встречаются в $haystack
. В $haystack
есть символы «A» (дважды), «X», «Y» и «Z», все из которых находятся в игле, поэтому результат должен быть 5 (с учетом регистра).
Есть ли какая-либо функция для этого в PHP или я должен сам ее программировать?
Заранее спасибо!
Вы можете рассчитать длину исходной строки и длину строки без этих символов. Различия между ними – количество матчей.
В основном,
$needle = 'AGUXYZ'; $haystack = 'Agriculture ID XYZ-A';
Вот часть, которая выполняет эту работу. В одной строке.
$count = strlen($haystack) - strlen(str_replace(str_split($needle), '', $haystack));
Объяснение: Первая часть не требует пояснений. Вторая часть – это длина строки без символов строки $needle
. Это делается путем замены всех вхождений любых символов внутри $needle
пустой строкой.
Чтобы сделать это, мы разделим $needle
в массив, после символа для каждого элемента, используя str_split
. Затем передайте его str_replace
. Он заменяет каждое появление любых элементов в массиве $search
пустой строкой.
Повторите это,
echo "Count = $count\n";
Вы получаете:
Граф = 5
Попробуй это;
function count_occurences($char_string, $haystack, $case_sensitive = true){ if($case_sensitive === false){ $char_string = strtolower($char_string); $haystack = strtolower($haystack); } $characters = str_split($char_string); $character_count = 0; foreach($characters as $character){ $character_count = $character_count + substr_count($haystack, $character); } return $character_count; }
Использовать;
$needle = 'AGUXYZ'; $haystack = 'Agriculture ID XYZ-A'; print count_occurences($needle, $haystack);
Вы можете установить для третьего параметра значение false
чтобы игнорировать регистр.
Нет встроенной функции, которая обрабатывает наборы символов, но вы просто используете функцию substr_count в цикле как таковой:
<?php $sourceCharacters = str_split('AGUXYZ'); $targetString = 'Agriculture ID XYZ-A'; $occurrenceCount = array(); foreach($sourceCharacters as $currentCharacter) { $occurrenceCount[$currentCharacter] = substr_count($targetString, $currentCharacter); } print_r($occurrenceCount); ?>
Для этого нет конкретного метода, но этот встроенный метод может помочь вам:
$count = substr_count($haystack , $needle);
edit: Я только что сообщил об общем методе substr_count
.. в вашем конкретном случае вам нужно вызвать его для каждого символа внутри $ needle (спасибо @Alan Whitelaw)
Если вас не интересует распределение символов, вы можете использовать Regex
echo preg_match_all("/[$needle]/", $haystack, $matches);
который возвращает количество полных совпадений шаблонов (которые могут быть равны нулю) или FALSE
если произошла ошибка. Решение, предлагаемое выше, должно быть значительно быстрее.
Если распределение символов имеет какое-либо значение, вы можете использовать count_chars
:
$needle = 'AGUXYZ'; $haystack = 'Agriculture ID XYZ-A'; $occurences = array_intersect_key( count_chars($haystack, 1), array_flip( array_map('ord', str_split($needle)) ) );
Результатом будет массив с ключами, являющимися значениями ASCII символа.
Затем вы можете перебрать его с помощью
foreach($occurences as $char => $amount) { printf("There is %d occurences of %s\n", $amount, chr($char)); }
Вы все равно можете передать массив $occurences
array_sum
в array_sum
чтобы вычислить общее количество.
substr_count приблизит вас. Однако он не будет использовать отдельные символы. Таким образом, вы можете перебрать каждый символ в $needle
и вызвать эту функцию, суммируя подсчеты.
Существует функция PHP substr_count
чтобы подсчитать количество экземпляров символа в строке. Было бы тривиально расширять его для нескольких символов:
function substr_multi_count ($haystack, $needle, $offset = 0, $length = null) { $ret = 0; if ($length === null) { $length = strlen($haystack) - $offset; } for ($i = strlen($needle); $i--; ) { $ret += substr_count($haystack, $needle, $offset, $length); } return $ret; }
я сделаю что-то вроде: разделите строку на chars ( str_split
), а затем используйте array_count_values
, чтобы получить массив каждого символа, сколько раз происходит.
$needle = 'AGUXYZ'; $string = "asdasdadas asdadas asd asdsd"; $array_chars = str_split($string); $value_count = array_count_values($array_chars); for($i=0;$i<count($needle);$i++) echo $needle[$i]. " is occur " . ($value_count[$needle[$i]] ? $value_count[$needle[$i]] : '0')." times";
У меня есть рекурсивный метод для преодоления этого:
function countChar($str){ if(strlen($str) == 0) return 0; if(substr($str,-1) == "x") return 1 + countChar(substr($str,0,-1)); return 0 + countChar(substr($str,0,-1)); } echo countChar("xxSR"); // 2 echo countChar("SR"); // 0 echo countChar("xrxrpxxx"); // 5