PHP如何从带多级编号的不规则换行文本中分离编号与对应内容
问题根源
直接用explode(". ", $text)拆分的方案,没有区分「编号结构里的点+空格」和「正文内容里的点+空格」,只要正文出现句号加空格的格式就会被错误拆分,完全没有利用编号本身的结构特征。
待提取的编号有明确可识别的规则:
- 出现在行/段落的最开头
- 由数字和点组成,支持多级结构(如
82.、82.2.这类格式) - 编号结束后接空格,后续为条目内容,内容可跨多行、可包含任意标点
正确实现方案
用正则匹配精准识别行首的合法编号,将编号和后续直到下一个编号前的所有内容做绑定,完全不会受正文里的句号、空行、换行影响。
实现代码
<?php // 原始待处理文本 $text = "81. Text1 82. Text2 82.1. Some text3 82.2. Some long text goes there in two or more lines... Some more text goes here... 83. Text4 84. Text5"; /* 正则模式说明: /^(\d+(?:\.\d+)*\.)\s+(.*?)(?=^\d+(?:\.\d+)*\.|\Z)/ms m修饰符:开启多行模式,让^匹配每一行的开头 s修饰符:让.可以匹配换行符,支持抓取跨多行的条目内容 */ preg_match_all('/^(\d+(?:\.\d+)*\.)\s+(.*?)(?=^\d+(?:\.\d+)*\.|\Z)/ms', $text, $matches); // 整理为 编号=>对应内容 的结构化数组 $items = []; for ($i = 0; $i < count($matches[0]); $i++) { $itemNo = trim($matches[1][$i]); $itemContent = trim($matches[2][$i]); $items[$itemNo] = $itemContent; } // 打印结果测试 print_r($items); ?>
运行结果
执行后输出的结构化结果完全符合提取要求:
Array ( [81.] => Text1 [82.] => Text2 [82.1.] => Some text3 [82.2.] => Some long text goes there in two or more lines... Some more text goes here... [83.] => Text4 [84.] => Text5 )
方案说明
- 自动过滤文本里的随机空行、内容首尾的多余空白
- 支持任意层级的数字编号(
1.、1.1.、1.1.1.这类格式都可正常识别) - 条目内容无论跨多少行、内容里包含多少个
.格式的断句,都不会出现误拆分 - 后续如果需要适配其他编号格式,只需要微调正则规则即可,扩展性远高于简单字符串拆分
内容的提问来源于stack exchange,提问作者user2534787
相关产品推荐
相关产品推荐

