条码扫描字符串转变量:PHP代码解析错误修正需求
条码解析PHP代码修正方案
问题根源
你的代码未正确处理扫描字符串中空格分隔的主数据区与序列号区,导致批次号的匹配范围覆盖到了后续的序列号内容,同时序列号因未单独处理而提取失败。
修正思路
- 先按空格拆分扫描字符串,分离主数据段(包含GTIN、生产日期、过期日期、批次号)和序列号段;
- 对主数据段,通过正则匹配各标识对应的字段,其中批次号需限制匹配到下一个标识或主数据结束;
- 单独从序列号段提取21开头的序列号内容。
修正后代码
<?php $scanString = "0109556135082301172207211060221967 21Sk4YGvF8"; // 按空格分割主数据与序列号部分,最多拆分一次 [$mainData, $serialPart] = explode(' ', $scanString, 2); $gtin = ''; $productionDate = ''; $expiryDate = ''; $batchNumber = ''; $serialNumber = ''; // 提取01标识对应的14位GTIN if (preg_match('/01(\d{14})/', $mainData, $matches)) { $gtin = $matches[1]; } // 提取11标识对应的6位YYMMDD格式生产日期 if (preg_match('/11(\d{6})/', $mainData, $matches)) { $productionDate = $matches[1]; } // 提取17标识对应的6位YYMMDD格式过期日期 if (preg_match('/17(\d{6})/', $mainData, $matches)) { $expiryDate = $matches[1]; } // 提取10标识的批次号(最多20位,匹配到下一个标识或主数据结束) if (preg_match('/10([A-Za-z0-9]{1,20})(?=(01|11|17|$))/', $mainData, $matches)) { $batchNumber = $matches[1]; } // 提取21标识的序列号(最多20位) if (preg_match('/21(.{1,20})/', $serialPart, $matches)) { $serialNumber = $matches[1]; } // 输出结果 var_dump([ 'GTIN' => $gtin, '生产日期' => $productionDate, '过期日期' => $expiryDate, '批次号' => $batchNumber, '序列号' => $serialNumber ]); ?>
关键说明
- 使用
explode(' ', $scanString, 2)确保只拆分一次,避免字符串中存在多个空格时出错; - 批次号的正则使用正向预查
(?=(01|11|17|$)),严格限制匹配范围,不会包含后续的其他标识或序列号内容; - 序列号单独从空格后的片段提取,确保不会被主数据的匹配逻辑干扰。
测试输出
针对示例输入,代码会输出:
array(5) { ["GTIN"]=> string(14) "09556135082301" ["生产日期"]=> string(0) "" ["过期日期"]=> string(6) "220721" ["批次号"]=> string(8) "60221967" ["序列号"]=> string(8) "Sk4YGvF8" }
(注:示例输入中无11标识的生产日期,因此该字段为空,符合预期)
内容的提问来源于stack exchange,提问作者devilgg86
相关产品推荐
相关产品推荐

