如果你写过PDF解析脚本,一定经历过这种绝望:跑一遍通用文本提取器,原本整齐的表格变成一堵文字墙,所有列被暴力压成垂直堆叠。更糟的是换用表格提取器——它开始到处 hallucinate(产生幻觉)。加粗标题带下划线? parser 认定这是 1×1 表格。段落间的水平分隔线?砰,幽灵表格诞生。

问题根源在于大多数 PDF 解析器采用严格的顺序流水线。它们扫描所有线条,扫描所有文字,然后简单粗暴地混在一起。我受够了这种"机器式阅读",于是重新设计了提取流水线——让 parser 像人类一样"看见"文档。

打开网易新闻 查看精彩图片

这就是上下文感知 PDF 提取的数学原理。

盲目提取的灾难

我们之前的流水线是这样工作的:找出所有水平和垂直线段(H-segs 和 V-segs),丢进 LatticeReconstructor 找交叉网格,每个网格都当表格处理,再用严格的"点是否在框内"判断把所有文字塞进这些网格。

这种设计对图文混排文档是灾难。段落里一条装饰性下划线会让 LatticeReconstructor panic,强行造表。表格单元格里的文字因坐标抖动稍微偏移,"点-框检测"就失败,文字直接从输出里消失。

我需要 parser 理解上下文

上下文分类器的介入

我构建了 contextClassifier。它不再把 PDF 当作形状和文字的容器,而是遍历文档,将每个元素归类到空间有界的类型区域:TABLE、PARAGRAPH、HEADING、LIST、IMAGE。

但机器怎么区分表格边框和装饰下划线?用邻近度数学。

代码逻辑很直接:遍历每条水平线段,计算其中点纵坐标 hY;遍历每个文字元数据,计算 hY 与文字基线纵坐标 tm.vy 的垂直距离 yDist。如果 yDist 在 -1 到 5 像素之间,且水平方向与文字重叠,这条线就是下划线而非表格边框。

在表格重建前标记并剔除这些下划线,99% 的幽灵表格被消灭。

文字作用域:告别碰撞

表格检测完成后,我们计算表格网格的精确边界框。contextClassifier 不再把整份文档的文字丢给表格构建器,而是只捞取物理上位于该边界框内的文字项。这种"物理居住"检查替代了粗暴的全局匹配,从根本上消除了文字错配和消失的问题。

这套数学框架的核心洞察很简单:PDF 不是几何图形的随机堆叠,而是人类视觉意图的编码。用像素级的邻近关系重建这种意图,机器才能停止幻觉,开始理解。