PHP提取文本中以S21.G00.30.001开头的重复块存入数组
PHP逐行读取文件提取定界分隔的不定长重复数据块
实现逻辑
核心思路是在逐行遍历的过程中维护临时容器存储当前块内容,遇到块起始标识就完成上一个块的归档,开启新块的收集:
- 初始化二维结果数组存储所有块,初始化一维临时数组存储当前正在收集的块内容
- 逐行读取文件时,优先保留你原有提取固定行(网站地址、公司名称、版本号等)的逻辑,不影响原有字段提取
- 每次读到行内容,先判断是否匹配块起始前缀
S21.G00.30.001:- 匹配且临时数组非空:说明上一个块已经读取到末尾,将临时数组存入结果集,清空临时数组后将当前行作为新块的首行存入
- 不匹配且临时数组非空:说明当前行属于正在收集的块,直接追加到临时数组
- 文件读取结束后,将最后一段存在临时数组里的块内容存入结果集,避免遗漏最后一个块
可直接复用的代码示例
代码完全兼容你已有的fopen+fgets+str_starts_with读取逻辑,不需要重构原有代码:
<?php // 存储所有提取到的数据块,最终输出的二维数组 $blockList = []; // 临时存储当前正在收集的单块内容 $currentBlock = []; // 块起始固定前缀 $startFlag = 'S21.G00.30.001'; $fileHandle = fopen('你的目标文件路径', 'r'); if ($fileHandle) { while (($line = fgets($fileHandle)) !== false) { // 按需选择是否去除行首尾换行、空白字符,不需要可删除 $line = trim($line); // 按需选择是否跳过空行,不需要可删除 if ($line === '') continue; // --- 你原有的固定行字段提取逻辑放在这里即可,不会冲突 --- // 例如提取网站地址、公司名称、版本号的代码... // --------------------------------------------------- // 检测到块起始行 if (str_starts_with($line, $startFlag)) { // 已经在收集块的状态下,先归档上一个完整块 if (!empty($currentBlock)) { $blockList[] = $currentBlock; } // 初始化新块,写入首行 $currentBlock = [$line]; } else { // 处于块收集状态时,追加当前行到当前块 if (!empty($currentBlock)) { $currentBlock[] = $line; } } } // 文件读取完成后,归档最后一个未存入的块 if (!empty($currentBlock)) { $blockList[] = $currentBlock; } fclose($fileHandle); } // 后续可直接遍历$blockList处理每个块的行内容 ?>
说明
- 最终生成的
$blockList为标准二维数组,第一层索引为块序号(从0开始计数),第二层元素为对应块内的每一行原文,完全匹配后续字段读取的结构要求 - 逻辑自动适配块长度不固定、不同块内容存在差异的场景,只要块以指定前缀作为起始和分隔标记,就能正确切分,不会出现内容串块、首尾行遗漏的问题
- 可根据你的实际文件格式,灵活调整是否保留trim处理、空行跳过的逻辑
内容的提问来源于stack exchange,提问作者hous
相关产品推荐
相关产品推荐

