PHP подсчитывает и отделяет текст от текстового файла

Допустим, внутри текстового файла находится эта информация:

<Amanda> Hi there, how are you?
<Jack> Hi, im fine 
.
.
.
.
<Jack> see you later

Я хочу подсчитать слова, которые сказал каждый пользователь, вывод должен быть, например, таким

Amanda: 50
Jack: 40

Сначала я хочу не считать <Amanda> или <Jack>, а затем я хочу подсчитать каждое сказанное ими слово и вставить его в переменные Аманда и Джек.

Это то, что я сделал

    $usercount1 = 0;
    $usercount2 = 0;  

    //Opens a file in read mode  
    $file = fopen("logfile.txt", "r");  
    //Gets each line till end of file is reached  
    while (($line = fgets($file)) !== false) {  
        //Splits each line into words
        $words = explode(" ", $line);  
        $words = explode("<Amanda>", $line);  
        //Counts each word  
        $usercount1 = $usercount1 + count($words);  
    }

    while (($line = fgets($file)) !== false) {  
        //Splits each line into words  
        $words = explode(" ", $line);
        //Counts each word  
        $usercount2 = $usercount2 + count($words);  
    } 

Что вы уже пробовали? Можете ли вы показать свой PHP-код?

Apodemus 17.04.2023 10:20

Возможно, вы захотите взглянуть на это: stackoverflow.com/questions/65370800/…

Apodemus 17.04.2023 10:23

Сначала я хочу не считать <Аманду> или <Джек>, а затем я хочу подсчитать каждое сказанное ими слово и вставить его в переменные Аманда и Джек.

Unkown Kid 17.04.2023 10:29

Если вы не хотите, чтобы он считал «Аманда» и «Джек», вы можете использовать str_replace, чтобы удалить их из строки, прежде чем вы взорвете ее и подсчитаете слова.

droopsnoot 17.04.2023 10:49

Если каждая строка начинается с имени в угловых скобках, которое вы хотите исключить, вы можете просто вычесть единицу из подсчета.

droopsnoot 17.04.2023 10:50

Покажите нам, что вы пытались решить проблему. Для меня, если каждая строка начинается с имени пользователя, я бы взорвал строку, а затем увеличил счетчик, что-то вроде $count[$words[0]] += (count($words)-1) во втором цикле, но может быть что-то еще, о чем вы не упомянули.

droopsnoot 17.04.2023 10:51
3v4l.org/0bM6Y (замените foreach, использованный в примере, без цикла while по данным файла, на свой.)
CBroe 17.04.2023 11:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
7
80
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Насколько я понимаю, это может быть возможным решением.


// Input
$input = "<Amanda> Hi there, how are you?\n<Jack> Hi, im fine \n <Jack> see you later";

// Initialize counters
$amandaCount = 0;
$jackCount = 0;

// Split input by lines
$lines = explode("\n", $input);

// Loop over lines
foreach ($lines as $line) {
  // Remove user tags
  $cleanLine = preg_replace("/<.+?>/", "", $line);
  
  // Split line into words
  $words = str_word_count($cleanLine, 1);
  
  // Count words per user
  if (strpos($line, "<Amanda>") !== false) {
    $amandaCount += count($words);
  } elseif (strpos($line, "<Jack>") !== false) {
    $jackCount += count($words);
  }
}

// Output
echo "Amanda: $amandaCount\n";
echo "Jack: $jackCount\n";
Ответ принят как подходящий

Я бы выбрал более общий подход. Таким образом, вы можете проанализировать всех пользователей. Используя черный список, просто исключите их.

  • Сначала пройдитесь по всем строкам и сопоставьте имя пользователя и текст.
  • Восстановите структуру данных путем повторения и подсчета с использованием черного списка.

Черный список отформатирован таким образом, потому что поиск ключей выполняется быстрее, чем поиск значений.

$input = <<<'_TEXT'
<Amanda> Hi there, how are you?
<Jack> Hi, im fine
<Jack> see you later
<John> Hello World, my friends!
<Daniel> Foo!
_TEXT;
preg_match_all('/^<([^>]+)>(.*?)$/m', $input, $matches);

$blacklist = ['Amanda' => 1, 'Jack' => 1];
$words = [];
foreach ($matches[2] as $index => $match) {
    $user = $matches[1][$index];
    if (isset($blacklist[$user])) {
        continue;
    }
    $words[$user] = ($words[$user] ?? 0) + str_word_count($match);
}
print_r($words);
Array
(
    [John] => 4
    [Daniel] => 1
)

Большое спасибо за ваше решение. Могу я узнать как это?? работает ($words[$user] ?? 0)

Unkown Kid 17.04.2023 14:32

Конечно, это нулевой оператор объединения. Это эквивалентно isset($words[$user]) ? $words[$user] : 0; Таким образом, он проверяет, существует ли ключ, если он существует, он возвращает значение, иначе 0.

Markus Zeller 17.04.2023 15:42

Я бы реализовал имена из черного списка в регулярном выражении, чтобы отфильтровать их как можно раньше.

Отрицательный просмотр вперед гарантирует, что Аманда и Джек исключены. (?!Amanda>|Jack>)

Модификатор шаблона m изменяет значение привязки ^ («начало строки») на привязку «начало строки».

Круглые скобки вокруг подшаблона имени создадут группу захвата 1 (доступную как элемент [1]). \K перезапустит сопоставление полной строки, поэтому подстрока слов, разделенных пробелами, будет доступна через [0].

Используйте синтаксис деструктурирования в foreach() для удобных переменных.

Код: (Демо)

preg_match_all(
    '/^<((?!Amanda>|Jack>)[^>]+)> \K.+/m',
    $chat,
    $matches,
    PREG_SET_ORDER
);
$result = [];
foreach ($matches as [$words, $name]) {
    $result[$name] = ($result[$name] ?? 0) + str_word_count($words);
}
var_export($result);

Другие вопросы по теме