本文介绍两种高效提取相机媒体文件名中前8位日期(如 20251215_083437.jpg → 2025-12-15)的方法:修正正则表达式匹配逻辑,以及更推荐的 datetime::createfromformat() 方案。
在处理数码相机导出的图片或视频文件(如 20251215_083437.jpg、20250401_192210.MP4)时,其文件名通常以 YYYYmmDD 开头,这是组织归档目录(如 /2025/12/15/)的关键依据。虽然正则表达式看似直观,但初学者常因锚点误用和捕获组索引混淆导致提取失败。
原始代码中的两个关键问题需修正:
修正后的正则方案如下:
$value = '20251215_083437.jpg';
if (preg_match('/^(\d{4})(\d{2})(\d{2})/', $value, $matches)) {
$year = $matches[1]; // "2025"
$month = $matches[2]; // "12"(注意:原问题示例写为 Month11,实为笔误,应为12)
$day = $matches[3]; // "15"
echo "Year{$year} Month{$month} Day{$day}"; // 输出:Year2025 Month12 Day15
}⚠️ 注意:$matches[0] 永远是整个匹配的子串(如 "20251215"),捕获组从索引 1 开始依次对应 () 内的内容。
正则仅做字符串切分,缺乏日期校验(例如 20251399 会被错误提取)。使用 DateTime 类不仅能精准解析,还能自动验证日期有效性,并支持灵活格式化:
$value = '20251215_083437.jpg'; $dateString = substr($value, 0, 8); // 安全截取前8位 $date= \DateTime::createFromFormat('Ymd', $dateString); if ($date === false) { throw new InvalidArgumentException("Invalid date format in filename: {$value}"); } // 按需输出结构化信息 echo "Year{$date->format('Y')} Month{$date->format('m')} Day{$date->format('d')}\n"; // 输出:Year2025 Month12 Day15 // 或直接生成标准格式路径 echo $date->format('Y/m/d'); // 输出:2025/12/15
该方案优势显著: