计算UTF-8字符串中每个单词的出现次数



我被导师分配的一个问题卡住了,他想让我写一个PHP脚本,读取UTF-8编码的文件内容,并返回每个单词出现的次数作为json。

文件内容语言为俄文西里尔文。

下面是示例文本

Он бледен. Мыслит страшный путь.
В его душе живут виденья.
Ударом жизни вбита грудь,
А щеки выпили сомненья.
Клоками сбиты волоса,
Чело высокое в морщинах,
Но ясных грез его краса
Горит в продуманных картинах.
Сидит он в тесном чердаке,
Огарок свечки режет взоры,
А карандаш в его руке
Ведет с ним тайно разговоры.
Он пишет песню грустных дум,
Он ловит сердцем тень былого.
И этот шум… душевный шум…
Снесет он завтра за целковый.

根据我的研究,PHP的预定义字符串函数可以无缝地处理这个问题,只有在它必须是ASCII编码的条件下。在这种情况下,我们是否有一些第三方库或api来处理其他非英语语言的utf-8编码字符串?

使用mb_string函数:

<?php
$str = "Он бледен. Мыслит страшный путь.
В его душе живут виденья.
Ударом жизни вбита грудь,
А щеки выпили сомненья.
Клоками сбиты волоса,
Чело высокое в морщинах,
Но ясных грез его краса
Горит в продуманных картинах.
Сидит он в тесном чердаке,
Огарок свечки режет взоры,
А карандаш в его руке
Ведет с ним тайно разговоры.
Он пишет песню грустных дум,
Он ловит сердцем тень былого.
И этот шум… душевный шум…
Снесет он завтра за целковый.";

$words = preg_split('/[ .,-?!:;'"nr]+/', 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);

这个解决方案将文本分割成一个数组,然后该数组包含单词。正则表达式只是一种方法,需要改进。然后用array_count_values来求值。

$result = array_count_values(preg_split("~[ ,.;rnt]+~u",$str, -1, PREG_SPLIT_NO_EMPTY));

这里有大写和小写的区别。

演示:https://3v4l.org/5iVnX

如果只有一个单词的第一个字母不被区分,或者像化妆这样的单词被识别为一个单词,代码就会变得更广泛。

function mb_word_count($string, $mode = MB_CASE_TITLE, $characters = null){
$string = mb_convert_case($string, $mode, "UTF-8");
$addChars = $characters ? preg_quote($characters, '~') : "";
$regEx = "~[^p{L}0-9".$addChars."]+~u";
return array_count_values(preg_split($regEx,$string, -1, PREG_SPLIT_NO_EMPTY));
}

mb_word_count函数返回一个数组,其中所有单词作为键,它们的数字作为值。像str2hex这样的人工单词被识别为一个单词。只有单词的第一个字母不区分大小写(MB_CASE_TITLE)。其他模式可以从mb_convert_case中选择。附加字符可以用$characters定义,然后将其视为字母。

最新更新