Получить наиболее часто используемые слова со специальными символами

Я хочу получить наиболее часто используемое слово из массива. Единственная проблема заключается в том, что шведские символы (Å, Ä и Ö) будут отображаться только как .

$string = 'This is just a test post with the Swedish characters Å, Ä, and Ö. Also as lower cased characters: å, ä, and ö.';
echo '<pre>';
print_r(array_count_values(str_word_count($string, 1, 'àáãâçêéíîóõôúÀÁÃÂÇÊÉÍÎÓÕÔÚ')));
echo '</pre>';

Этот код выведет следующее:

Array
(
[This] => 1
[is] => 1
[just] => 1
[a] => 1
[test] => 1
[post] => 1
[with] => 1
[the] => 1
[Swedish] => 1
[characters] => 2
[�] => 1
[�] => 1
[and] => 2
[�] => 1
[Also] => 1
[as] => 1
[lower] => 1
[cased] => 1
[�] => 1
[�] => 1
[�] => 1
)

Как я могу сделать так, чтобы «видеть» шведские символы и другие специальные символы?

3

Решение

Вот решение с регулярным выражением, использующее пунктуацию Unicode, чтобы разделить «слова», а затем просто число вхождений регулярного массива.

array_count_values(preg_split('/[[:punct:]\s]+/u', $string, -1, PREG_SPLIT_NO_EMPTY));

Производит:

Array
(
[This] => 1
[is] => 1
[just] => 1
[a] => 1
[test] => 1
[post] => 1
[with] => 1
[the] => 1
[Swedish] => 1
[characters] => 2
[Å] => 1
[Ä] => 1
[and] => 2
[Ö] => 1
[Also] => 1
[as] => 1
[lower] => 1
[cased] => 1
[å] => 1
[ä] => 1
[ö] => 1
)

Это было протестировано в консоли Unicode, вы можете использовать кодировку, если вы используете браузер. Либо сделать <meta> пометить или установить кодировку в вашем браузере или отправить заголовки PHP.

1

Другие решения

Все это работает при условии, что вы используете UTF-8.

Вы можете принять наивный подход, используя preg_split() разделить вашу строку на любой разделитель, пунктуацию или управляющий символ.

preg_split пример:

$split = preg_split('/[\pZ\pP\pC]/u', $string, -1, PREG_SPLIT_NO_EMPTY);
print_r(array_count_values($split));

Выход:

Array
(
[This] => 1
[is] => 1
[just] => 1
[a] => 1
[test] => 1
[post] => 1
[with] => 1
[the] => 1
[Swedish] => 1
[characters] => 2
[Å] => 1
[Ä] => 1
[and] => 2
[Ö] => 1
[Also] => 1
[as] => 1
[lower] => 1
[cased] => 1
[å] => 1
[ä] => 1
[ö] => 1
)

Это прекрасно работает для данной строки, но не обязательно разделяет слова в зависимости от локали. Например, сокращения, такие как «не», будут разбиты на «нет» и «т».


К счастью, Intl расширение добавляет множество функций для работы с такими вещами в PHP 7.

План будет заключаться в следующем:

  • *нормировать вход с Normalizer::normalize() чтобы убедиться, что все графемы закодированы в согласованном порядке. Например ä может быть закодирован и, следовательно, подсчитан несколькими способами:

    • U + 00E4 «ЛАТИНСКОЕ МАЛЕНЬКОЕ ПИСЬМО А С ДИАРЕЗОМ» или
    • U + 0061 «МАЛЕНЬКОЕ ПИСЬМО А ЛАТИНЫ», за которым следует U + 0308 «ДИАРЕЗИС КОМБИНИРОВАНИЯ»
  • Получить IntlBreakIterator который разбивает слова в зависимости от локали IntlBreakIterator::createWordInstance(). Это понимает, что составляет «слово» для данной локали, включая обработку сокращений типа «не».

  • Получить его IntlPartsIterator с помощью IntlBreakIterator::getPartsIterator() для удобства перебора фрагментов текста.

  • Пропускайте вещи, которые вас не волнуют, через IntlChar::ispunct() а также IntlChar::isspace()

(* Обратите внимание, что вы, вероятно, захотите выполнить нормализацию независимо от того, какой метод вы используете, чтобы разбить строку — это было бы целесообразно сделать до preg_split выше или что вы решите пойти.)

Международный пример:

$string = Normalizer::normalize($string);

$iter = IntlBreakIterator::createWordInstance("sv_SE");
$iter->setText($string);
$words = $iter->getPartsIterator();

$split = [];
foreach ($words as $word) {
// skip text fragments consisting only of a space or punctuation character
if (IntlChar::isspace($word) || IntlChar::ispunct($word)) {
continue;
}
$split[] = $word;
}

print_r(array_count_values($split));

Выход:

Array
(
[This] => 1
[is] => 1
[just] => 1
[a] => 1
[test] => 1
[post] => 1
[with] => 1
[the] => 1
[Swedish] => 1
[characters] => 2
[Å] => 1
[Ä] => 1
[and] => 2
[Ö] => 1
[Also] => 1
[as] => 1
[lower] => 1
[cased] => 1
[å] => 1
[ä] => 1
[ö] => 1
)

Это более многословно, но может быть целесообразно, если вы предпочитаете ICU (библиотека, поддерживающая расширение Intl), чтобы сделать тяжелую работу, когда дело доходит до понимания того, что составляет слово.

4

Мне удалось удалить знак adding, добавив ÅåÄäÖö в àáãâçêéíîóõôúÀÁÃÂÇÊÉÍÎÓÕÔÚ,

0
По вопросам рекламы [email protected]