БлогNot. PHP: извлекаем из текста числа и считаем их "самые нужные" характеристики

PHP: извлекаем из текста числа и считаем их "самые нужные" характеристики

Такой вот мини-сервис понадобился сегодня, а стирать жалко.

Скрипт позволяет извлечь из текстовых данных числовые значения, занести их в отдельный список и подсчитать для них те же 5 величин, которые Excel предлагает вычислить по своей "быстрой" кнопке "Автосумма" и которые чаще всего нам нужны, то есть, количество, сумму, арифметическое среднее, минимум и максимум.

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

Исходник частично отсюда, только ещё упрощён и снабжён filter_var вместо регулярок. Проверено в XAMPP с PHP 7.3.3.

Чтобы не "бегать" по массиву несколько раз и уменьшить время выполнения скрипта, арифметические характеристики массива ищутся прямо в процессе его формирования, а не стандартными функциями, каждая из которых, по-видимому, сделает по массиву отдельный проход.

Результаты выводятся всегда в обычной (не научной) форме записи вещественных чисел с выбранным количеством знаков в дробной части, для такого форматирования применяется стандартная sprintf.

Разумеется, огромные, но ещё интерпретируемые как числа величины, вроде 1e301, могут сбить с толку наш расчёт, поэтому проверяйте список полученных числовых значений. Он выводится одним абзацем, а значит, может быть выделен просто тройным кликом мыши.

Вот скриншот работы сервиса и его исходный код, который очень компактен. Код не формирует обрамления HTML документа и, вообще говоря, предполагает работу в кодировке Юникода UTF-8 (из-за регулярного выражения для разбиения содержимого <textarea> на лексемы).

извлечение чисел и занесение их в массив, скриншот
извлечение чисел и занесение их в массив, скриншот
<?php 
 $data='';
 if (isset($_POST['data'])) $data = strip_tags(trim($_POST['data']));
 $digits = 3;
 if (isset($_POST['digits'])) $digits = intval(strip_tags(trim($_POST['digits'])));
 if ($digits<0 or $digits>9) $digits = 3;
 echo '<p>Введите или вставьте текст с числами:</p>
  <form method="post" action="'.$_SERVER['PHP_SELF'].'">
  <p><textarea name="data" rows="16" cols="80">'.$data.'</textarea></p>
  <p>Знаков в дробной части:
   <select name="digits" size="1">';
 for ($i=0; $i<10; $i++) echo '<option value="'.$i.'"'.($i==$digits?' selected':'').'>'.$i."\n";
 echo ' </select>
   <input type="submit" name="submit" value="Обработать"></form>
  </p>';
 if (isset($_POST['submit'])) {
  $array = preg_split ("/[\s,]+/msiu",$data);
  $numbers = [];
  $max = - INF;
  $min = INF;
  $sum = 0;
  foreach ($array as $d) {
   if (filter_var ($d, FILTER_VALIDATE_FLOAT)) {
    $numbers[] = $d;
    if ($d < $min) $min = $d;
    if ($d > $max) $max = $d;
    $sum += $d;
   }
  }
  $n = count($numbers);
  if ($n < 1) {
   echo '<p>Не обнаружено ни одного числа!</p>'; exit;
  }
  echo '<p>'.implode(' ',$numbers).'</p>';
  echo '<p>Количество: '.$n.'</p>';
  echo '<p>Минимум: '.sprintf("%.{$digits}F",$min).'</p>';
  echo '<p>Максимум: '.sprintf("%.{$digits}F",$max).'</p>';
  echo '<p>Сумма: '.sprintf("%.{$digits}F",$sum).'</p>';
  echo '<p>Среднее: '.sprintf("%.{$digits}F",$sum/$n).'</p>';
 }  
?>

теги: числа php сервис

26.03.2019, 16:46; рейтинг: 562