Home > OS >  Count occurrences of each word in UTF-8 string
Count occurrences of each word in UTF-8 string

Time:11-26

Am stuck with a problem assigned by my mentor who wants me to write a PHP script which reads a UTF-8 encoded file content and return the number of occurrences of each word as json.

The language of the file content is Russian Cyrillic.

Here is the Sample text

Он бледен. Мыслит страшный путь.
В его душе живут виденья.
Ударом жизни вбита грудь,
А щеки выпили сомненья.

Клоками сбиты волоса,
Чело высокое в морщинах,
Но ясных грез его краса
Горит в продуманных картинах.

Сидит он в тесном чердаке,
Огарок свечки режет взоры,
А карандаш в его руке
Ведет с ним тайно разговоры.

Он пишет песню грустных дум,
Он ловит сердцем тень былого.
И этот шум… душевный шум…
Снесет он завтра за целковый.

As per my research, PHP's predefined string functions can seamlessly handle this problem only under a condition that it must be ASCII encoded. In this case do we have some third party libraries or APIs to handle utf-8 encoded strings of other non English language.

CodePudding user response:

Use mb_string functions:

<?php

$str = "Он бледен. Мыслит страшный путь.
        В его душе живут виденья.
        Ударом жизни вбита грудь,
        А щеки выпили сомненья.

        Клоками сбиты волоса,
        Чело высокое в морщинах,
        Но ясных грез его краса
        Горит в продуманных картинах.

        Сидит он в тесном чердаке,
        Огарок свечки режет взоры,
        А карандаш в его руке
        Ведет с ним тайно разговоры.

        Он пишет песню грустных дум,
        Он ловит сердцем тень былого.
        И этот шум… душевный шум…
        Снесет он завтра за целковый.";


$words = preg_split('/[ .,-?!:;\'"\n\r] /', mb_strtolower($str));

$mp = [];

foreach ($words as $word) {
    if (!mb_strlen($word)) continue;
    
    if (!isset($mp[$word])) {
        $mp[$word] = 0;
    }
    $mp[$word]  ;
}

var_dump($mp);

CodePudding user response:

This solution splits the text into an array which then contains the words. The regular expression is just an approach and needs improvement. The evaluation is then done with array_count_values.

$result = array_count_values(preg_split("~[ ,.;\r\n\t] ~u",$str, -1, PREG_SPLIT_NO_EMPTY));

A distinction is made here between upper and lower case. If no distinction is to be made, mb_strtolower can be used.

Demo: https://3v4l.org/5iVnX

  • Related