Допустим, внутри текстового файла находится эта информация:
<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);
}
Возможно, вы захотите взглянуть на это: stackoverflow.com/questions/65370800/…
Сначала я хочу не считать <Аманду> или <Джек>, а затем я хочу подсчитать каждое сказанное ими слово и вставить его в переменные Аманда и Джек.
Если вы не хотите, чтобы он считал «Аманда» и «Джек», вы можете использовать str_replace, чтобы удалить их из строки, прежде чем вы взорвете ее и подсчитаете слова.
Если каждая строка начинается с имени в угловых скобках, которое вы хотите исключить, вы можете просто вычесть единицу из подсчета.
Покажите нам, что вы пытались решить проблему. Для меня, если каждая строка начинается с имени пользователя, я бы взорвал строку, а затем увеличил счетчик, что-то вроде $count[$words[0]] += (count($words)-1) во втором цикле, но может быть что-то еще, о чем вы не упомянули.






Насколько я понимаю, это может быть возможным решением.
// 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)
Конечно, это нулевой оператор объединения. Это эквивалентно isset($words[$user]) ? $words[$user] : 0; Таким образом, он проверяет, существует ли ключ, если он существует, он возвращает значение, иначе 0.
Я бы реализовал имена из черного списка в регулярном выражении, чтобы отфильтровать их как можно раньше.
Отрицательный просмотр вперед гарантирует, что Аманда и Джек исключены. (?!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);
Что вы уже пробовали? Можете ли вы показать свой PHP-код?