#php #string #utf-8
#php #строка #utf-8
Вопрос:
Я не хочу находить умный и эффективный способ подсчета количества разных альфа-символов в одной строке. Пример:
$str = "APPLE";
echo char_count($str) // should return 4, because APPLE has 4 different chars 'A', 'P', 'L' and 'E'
$str = "BOB AND BOB"; // should return 5 ('B', 'O', 'A', 'N', 'D').
$str = 'PLÁTANO'; // should return 7 ('P', 'L', 'Á', 'T', 'A', 'N', 'O')
Он должен поддерживать строки UTF-8!
Комментарии:
1. Подумайте о том, чтобы превратить его в массив символов (возможно, выбрасывая пробелы), а затем «унифицировать» массив. Если нет каких-либо требований к производительности (и анализ производительности показывает, что они не выполняются), тогда это довольно разумно и достаточно эффективно.
2. Какую кодировку кодировки будут иметь входные данные? UTF-8?
3. Да, UTF-8 символов. Забыл добавить. Я изменил свой исходный пост.
Ответ №1:
Если вы имеете дело с UTF-8 (что вам действительно следует учитывать, имхо), ни одно из опубликованных решений (с использованием strlen, str_split или count_chars) не будет работать, поскольку все они обрабатывают один байт как один символ (что, очевидно, неверно для UTF-8).
<?php
$treat_spaces_as_chars = true;
// contains hälöwrd and a space, being 8 distinct characters (7 without the space)
$string = "hällö wörld";
// remove spaces if we don't want to count them
if (!$treat_spaces_as_chars) {
$string = preg_replace('/s /u', '', $string);
}
// split into characters (not bytes, like explode() or str_split() would)
$characters = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
// throw out the duplicates
$unique_characters = array_unique($characters);
// count what's left
$numer_of_characters = count($unique_characters);
Если вы хотите удалить все символы, не являющиеся словами:
<?php
$ignore_non_word_characters = true;
// contains hälöwrd and PIE, as this is treated as a word character (Greek)
$string = "h,ä* l•π‘°’lö wörld";
// remove spaces if we don't want to count them
if ($ignore_non_word_characters) {
$string = preg_replace('/W /u', '', $string);
}
// split into characters (not bytes, like explode() or str_split() would)
$characters = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY);
// throw out the duplicates
$unique_characters = array_unique($characters);
// count what's left
$numer_of_characters = count($unique_characters);
var_dump($characters, $unique_characters, $numer_of_characters);
Комментарии:
1. Правильно, и я имею дело с UTF-8! Я отредактировал свой первоначальный вопрос.
2. Это решение работает, событие со строками UTF-8. Спасибо, Родни!
3. Я только что добавил еще один пример, который игнорирует все несимволы (знаки препинания и прочее), вы, вероятно, их тоже не считаете.
Ответ №2:
Просто используйте count_chars:
echo count(array_filter(count_chars($str)));
Массив, возвращаемый из count_chars()
, также сообщит вам, сколько каждого символа в строке.
Комментарии:
1. 1 Однако стоит отметить, что пробелы (и знаки препинания?) должен быть удален первым в соответствии с примером OP
2. @PrimozRome Это верно, он возвращает карту ascii (256 символов) с количеством каждого символа. Попробуйте то, что я предложил
3. @PrimozRome: Извиняюсь, я не фильтровал массив для нулевых значений, обновленных в ответе выше.
4. @JuanMendes: Я исправил ответ выше, одна строка, вероятно, предпочтительнее. Слава вашей функции, хотя 1
5. @JuanMendes правильно. Я вижу, да. Ваша функция работает правильно, но не для строк UTF-8. Но все еще приближаюсь к результату. Спасибо!
Ответ №3:
count_chars возвращает отображение всех символов ascii, сообщая вам, сколько каждого из них содержится в строке. Вот отправная точка для вашей собственной реализации.
function countchars($str, $ignoreSpaces) {
$map = array();
$len = strlen($str);
for ($i=0; $i < $len; $i ) {
if (!isset($map[$str{$i}])) {
$map[$str{$i}] = 1;
} else {
$map[$str{$i}] ;
}
}
if ($ignoreSpaces) {
unset($map[' ']);
}
return $map;
}
print_r(countchars('Hello World'));
Ответ №4:
Вот функция, которая сделает это, используя магию ассоциативных массивов. Работает в линейном времени. (большой O = log(n)
)
function uniques($string){
$arr = array();
$parts = str_split($string);
foreach($parts as $part)
$arr["$part"] = "yup";
return count($arr);
}
$str = "APPLE";
echo uniques($str); // outputs 4
Ответ №5:
Мой взгляд на это,
$chars = array_count_values(str_split($input));
Это даст вам ассоциативный массив уникальных букв в качестве ключа и количество вхождений в качестве значения.
Если вас не интересует количество вхождений,
$chars = array_unique(str_split($input));
$numChars = count($chars);