如何使用正则表达式正确提取文件中的结构化数据块
问题背景
尝试使用正则表达式(RegEx)解析如下结构的信息:
1. Data A. Data sub 1 B. Data sub 2 2. Data A. Data sub 1 B. Data sub 2 C. Data sub 3 D. Data sub 4 3. Data A. Data sub 1
上述每条信息单独占一行,原本可采用逐行遍历的方式处理,但希望直接通过正则完成解析任务。
实现目标
按块提取上述数据,单个数据块示例如下:
1. Data A. Data sub 1 B. Data sub 2
现有尝试
观察到数据存在固定规律,最初使用如下正则语句提取数据块:
(?s)(?=1.)(.*?)(?=(2. ))
该表达式可成功提取单个块,但如果块内容中包含表达式匹配的数字字符,提取得到的块就会不完整,造成输出内容损坏。
预期效果
完整提取所有数据块,不会因定义的起止匹配边界之间存在的相似字符或字符串,导致提取过程被意外中断。
解决方法
之前写的正则有两个明显缺陷:
- 没有锚定顶级编号的行首位置,只要块内部出现类似
2.的字符组合,就会被误判为块结束边界 - 硬编码了
1.、2.这类固定编号,无法自动提取所有序号对应的块
直接用下面的正则即可一次性匹配所有符合规则的数据块:
(?m)^\d+\. .*(?:\r?\n\s+[A-Z]\. .*)*
规则拆解:
(?m)开启多行匹配模式,让^可以匹配每一行的起始位置^\d+\.只认行首开头的数字+点+空格格式的顶级条目,不会把内容中间出现的数字加点误判为顶级条目.*匹配顶级条目所在行的剩余内容(?:\r?\n\s+[A-Z]\. .*)*匹配后续所有带前置缩进、以大写字母+点开头的子条目,直到碰到下一个行首的顶级数字条目才停止匹配
如果子项的缩进是固定长度,把\s+换成对应数量的空格(比如示例里的2个空格),匹配精度会更高。
内容的提问来源于stack exchange,提问作者Jonalca
相关产品推荐
相关产品推荐

