Laravel解析.DAT文件生成CSV时,AUTH CANCELLED相关数据段匹配失败的问题求助
Laravel解析.DAT文件生成CSV时,AUTH CANCELLED相关数据段匹配失败的问题求助
看起来你在Laravel里解析DAT交易文件时遇到了正则匹配的坑——明明数据里有AUTH CANCELLED相关内容,却一直触发“缺失段”的报错,没法提取想要的交易信息对吧?我帮你梳理下问题出在哪,再给你调整后的代码方案。
问题根源分析
先看你原来的第一个正则:
preg_match('/AUTH\s+CANCELLED\s+(.*?)\s+\d{14}XXXXXXXX/i', $line, $segmentMatch)
这里你想匹配AUTH CANCELLED到\d{14}XXXXXXXX之间的内容,但你的样本数据里根本没有\d{14}XXXXXXXX这个格式的字符串啊!样本里AUTH CANCELLED后面跟着的是日期+金额+手机号的长串(比如2025050800000000000000180000812345678),再后面是交易ID(20250508ABCXXXXXXXXX),你的正则结束条件完全不对,导致根本匹配不到任何内容,自然就触发了“缺失段”的报错。
另外,你要提取的字段其实都集中在AUTH CANCELLED后面的两个关键部分:
- 长串
2025050800000000000000180000812345678:包含交易日期(前8位)、金额(中间有效数字)、手机号(最后10位) - 交易ID段
20250508ABCXXXXXXXXX:需要后面的ABCXXXXXXXXX
所以我们可以直接把正则逻辑简化,一步匹配到这两个关键部分,再从中拆分出你要的字段。
修正后的代码实现
private function parseFileContent(string $content, string $fileName): Collection { $results = collect(); $lines = explode("\n", $content); foreach ($lines as $lineNumber => $line) { $line = trim($line); if (empty($line)) { continue; // 跳过空行,避免无效匹配 } // 直接匹配AUTH CANCELLED后面的两个核心段:长串(日期+金额+手机号) 和 交易ID段 if (preg_match('/AUTH\s+CANCELLED\s+(\d+)\s+(\d{8}[A-Z0-9]{5,})/i', $line, $matches)) { $transactionLongString = $matches[1]; $transactionIdFull = $matches[2]; // 从长串拆分基础字段 $transactionDate = substr($transactionLongString, 0, 8); // 前8位:20250508 $mobileNumber = substr($transactionLongString, -10); // 最后10位:0812345678 // 提取金额:去掉日期和手机号后的中间部分,去掉前导0后除以100转成金额格式 $amountRaw = substr($transactionLongString, 8, -10); $cleanAmount = ltrim($amountRaw, '0'); $amount = number_format(((int)($cleanAmount ?: '0')) / 100, 2, '.', ''); // 从交易ID段提取核心ID(去掉前8位日期前缀) $transactionId = substr($transactionIdFull, 8); // 用你原有的方法格式化交易日期 $formattedDate = $this->parseDate($transactionDate); $results->push([ 'file' => $fileName, 'line' => $lineNumber + 1, 'date' => $formattedDate, 'amount' => $amount, 'mobile_number' => $mobileNumber, 'transaction_id' => $transactionId, 'raw_line' => $line ]); } else { $this->warn("Skipping line {$lineNumber}: 未匹配到AUTH CANCELLED相关的交易核心段"); } } return $results; }
关键调整说明
- 核心正则优化:新正则
/AUTH\s+CANCELLED\s+(\d+)\s+(\d{8}[A-Z0-9]{5,})/i不再依赖固定长度的结束符,而是匹配:AUTH CANCELLED后的任意数字长串(兼容金额长度变化的情况)- 紧接着的交易ID段(8位日期前缀+至少5位字母数字组合)
- 字段拆分更灵活:用
substr直接从长串里拆分日期、手机号,中间部分作为金额原始值,避免嵌套正则的复杂度 - 增加空行处理:跳过空行减少无效报错,让日志更清晰
另外,如果你要实现每分钟定时解析并生成CSV的需求,记得在app/Console/Kernel.php里配置Laravel任务调度,比如:
protected function schedule(Schedule $schedule) { $schedule->call(function () { // 调用你的解析方法,将结果写入CSV文件 $content = file_get_contents(storage_path('transactions.dat')); $data = $this->parseFileContent($content, 'transactions.dat'); // 写入CSV逻辑 $headers = ['file', 'line', 'date', 'amount', 'mobile_number', 'transaction_id', 'raw_line']; $handle = fopen(storage_path('exports/transactions_'.now()->format('YmdHi').'.csv'), 'w'); fputcsv($handle, $headers); foreach ($data as $row) { fputcsv($handle, $row); } fclose($handle); })->everyMinute(); }
内容来源于stack exchange
相关产品推荐
相关产品推荐

