
本文详解如何将形如“dd.mm.yyyy|x,xxx”格式的日期-数值字符串,通过 explode 拆分为结构化数组,并按年月分组计算各月数值的算术平均值,全程使用 php 原生函数链式处理,兼顾可读性与实用性。
本文详解如何将形如“dd.mm.yyyy|x,xxx”格式的日期-数值字符串,通过 explode 拆分为结构化数组,并按年月分组计算各月数值的算术平均值,全程使用 php 原生函数链式处理,兼顾可读性与实用性。
在实际数据处理中,常遇到以空格分隔、含日期与带千位符数值的扁平化字符串(例如来自日志、CSV 片段或 API 响应)。本教程以典型场景为例:输入字符串中每项为 DD.MM.YYYY|X,XXX 格式,目标是按月份(MM.YYYY)聚合所有对应数值,并精确计算每月算术平均值。
核心思路分为三步:
- 字符串→二维数组:用 explode(' ', $input) 切分条目,再对每个条目 explode('|', ...) 提取日期与数值;
- 归组→月度数值数组:提取日期子串(如 04.01.2021 → 01.2021),清理数值中的逗号,按月键存入关联数组;
- 计算→月均值:对每个月份的数值数组调用 array_sum() / count() 得到平均值。
以下是完整、健壮的实现代码(兼容 PHP 7.4+,推荐 8.0+):
<?php $input = '04.01.2021|26,140 05.01.2021|26,225 06.01.2021|26,145 07.01.2021|26,145 08.01.2021|26,165 11.02.2021|26,240 12.02.2021|26,190';
// 步骤1:拆分为 [ [date, value], ... ] 结构
$pairs = array_map(
fn($item) => explode('|', trim($item)),
explode(' ', $input)
);
// 步骤2:按 "MM.YYYY" 分组,同时转换数值(移除逗号,转为数字)
$groupedByMonth = array_reduce(
$pairs,
function ($carry, $pair) {
if (count($pair) !== 2) return $carry; // 跳过格式异常项
[$date, $valueStr] = $pair;
// 提取 MM.YYYY(第3-6位为月,第7-10位为年,兼容4位年份)
$monthKey = substr($date, 3, 2) . '.' . substr($date, 6, 4);
$cleanValue = (float) str_replace(',', '', $valueStr);
$carry[$monthKey][] = $cleanValue;
return $carry;
},
[]
);
// 步骤3:计算每月平均值(自动跳过空数组)
$averagesPerMonth = array_map(
fn($values) => round(array_sum($values) / count($values), 3),
$groupedByMonth
);
print_r($averagesPerMonth);
// 输出示例:
// Array
// (
// [01.2021] => 26164
// [02.2021] => 26215
// )
✅ 关键注意事项:
- 日期提取鲁棒性:使用 substr($date, 3, 2) 提取月份、substr($date, 6, 4) 提取年份,严格依赖固定格式 DD.MM.YYYY;若输入年份为两位(如 21),请改用正则 preg_match('/\d{2}\.(\d{2})\.(\d{2,4})/', $date, $m) 并拼接 $m[2].$m[1];
- 数值清洗安全:str_replace(',', '', $valueStr) 仅移除逗号,floatval() 或 (float) 强制转换确保参与运算;若存在非数字字符(如空格、货币符号),建议前置 trim() 和正则过滤 preg_replace('/[^0-9.]/', '', $valueStr);
- 空值/异常处理:代码中已加入 count($pair) !== 2 校验,生产环境建议扩展为 try-catch 或自定义错误日志;
- 精度控制:round(..., 3) 保留三位小数,可根据业务需求调整(如金融场景用 bcdiv() 避免浮点误差)。
该方案无需循环遍历,全部基于函数式编程范式(array_map / array_reduce),逻辑清晰、易于测试与复用。你可将其封装为独立函数,例如 calculateMonthlyAverage(string $data): array,进一步提升工程化程度。










