如何订购从pdf中提取的文本?

How order text extracted from pdf?

我正在构建一个提取文本并将其保存到 txt 文件中的 pdf 解析器。
我通过跟踪所有内容对象,然后使用字体编码解码流来做到这一点。 我发现我有点挑战的是如何以正确的顺序放置文本,我不关心它的真实外观,我想要的只是序列的顺序,我不关心字体大小,space 文本之间...等等

如果我只关心订单,我该如何处理 Tm、Td、TD 和 T*?

另一个问题,有时一个内容对象包含来自 2 个不同页面的流,我如何知道下一页的流何时开始?

由于你的问题很笼统,这个回答也很笼统。

So how can I deal with Tm,Td,TD and T* if all I care about is the order?

只有几个主要选项:

  • 您可以忽略除显示运算符的文本之外的所有内容,尤其是您忽略提到的运算符。相关数量的文档允许以这种方式非常忠实地提取文本,因为这些文档中显示运算符的文本以自然阅读顺序出现。

    不过,考虑到您提出这个问题,似乎表明您遇到了不同构建的文档。

  • 如果有问题的文档被适当地标记,你可以使用内容流中的MCIDs结合文档结构树来排序(和分类!)您像以前一样提取的文本片段。对于标记的文档,这通常会产生合理的良好文本提取结果。

  • 否则,即使您“只”关心顺序,您也必须提取文本片段的确切位置以及这些片段本身,并最终对它们进行相应排序。这意味着不仅要考虑您提到的操作,还要考虑 cm(更改当前变换矩阵),q(保存当前图形状态),和 Q(恢复当前图形状态)。

    此外,对于范围广泛的文档的解决方案,您还必须分析布局以识别属于图形而不是主要文本流的多个列和文本。

当然这些主要选项可能会有一些变化,例如假设文本对象的顺序是正确的并且只在其中排序;这些可能允许忽略一些操作符,例如在刚才提到的例子中,可以忽略 cmqQ,因为它们在文本对象。

Another question sometimes one content object contains streams that are from 2 different pages how can I know when the streams of the next page started?

我不确定我是否理解正确。您的意思是从多个页面对象引用相同的内容流,这些页面对象只显示某些内容,可能是不同的部分?在那种情况下,您还必须提取文本片段的确切位置,并检查它们是在相应页面的裁剪框内部还是外部。

编辑

在评论中,您同时澄清并提供了示例数据。分析该数据会产生以下加法:

首先,并非您在第 16 页的内容流中标记为蓝色的所有内容都可以在第 17 页而不是第 16 页找到;例如很早(在“仔细查看对象 127”的第二行),您可以看到绘制页码 (16)Tj 的说明,它位于第 16 页,而不是第 17 页。

但确实,很快就会出现一大段文本对象,您只能在第 17 页而不是第 16 页的查看器中找到文本对象。原因是这些文本对象绘制在可见页面区域之外和外部当前剪辑路径!

更详细:

第16页和第17页的CropBox都是[ 0.0 0.0 481.89 680.315 ],即可见区域是canvas中带(0, 0)的部分在左下角和 (481.89, 680.315) 在右上角。

然后你在第16页你标记为蓝色的部分前面找到了如下说明:

0 0 481.89 680.315 re
W n

这会将当前剪辑路径与左下角为 (0, 0) 且右上角为 (481.89, 680.315) 的矩形相交。

因此,由于两个原因,第 16 页上那个框外的所有内容都是不可见的。

但该内容中以蓝色标记的以下文本对象在具有负 x 坐标的位置绘制文本!例如,在上面的剪辑路径更改指令之后立即:

BT
0 0 0 1 k
/GS1 gs
/C2_0 1 Tf
15 0 0 15 -441.875 556.9449 Tm
[<0003007000640059006E005F004300D0>-48<00030044004C>-47<000300CA006E>1<0066003D00ED>-48<000300BA007B0065005C003D>-48<000300700059006E005F005500D0>-47<0003007000650063009D004300D0>-48<0003007F006800FD00DA>-48<00030007000C000C000C0008>-45<0003006E006900CC>-47<000300EF007B00640052>-49<000300BA007B005F003D00ED>-48<000300EC007B004100ED>-48<00030101>-47<0003007B0065002200D0>]TJ
ET
EMC 
/Span <</MCID 243 >>BDC 
BT
/C2_0 1 Tf
15 0 0 15 -441.875 534.9449 Tm
[<0003008B0053007D003D>-289<0003007000650063009D0043006E003D>-289<000300D2007B00680062004300D0>-291<000300E50077>]TJ
ET
EMC 

那些文本矩阵设置指令的第五个条目(Tm)本质上是x坐标,下面的文本绘制指令将从该坐标开始从左到右绘制文本。 -441.875 的值显然在上面提到的框外。

如果您查看以下第 17 页的内容流,您会发现绘制相同文本的类似说明:

BT
/C2_0 1 Tf
15 0 0 15 40.0148 556.9449 Tm
[<0003007000640059006E005F004300D0>-48<00030044004C>-47<000300CA006E>1<0066003D00ED>-48<000300BA007B0065005C003D>-48<000300700059006E005F005500D0>-47<0003007000650063009D004300D0>-48<0003007F006800FD00DA>-48<00030007000C000C000C0008>-45<0003006E006900CC>-47<000300EF007B00640052>-49<000300BA007B005F003D00ED>-48<000300EC007B004100ED>-48<00030101>-47<0003007B0065002200D0>]TJ
ET
EMC 
/Artifact <</O /Layout >>BDC 
BT
/C2_0 1 Tf
15 0 0 15 40.0148 534.9449 Tm
[<0003008B0053007D003D>-289<0003007000650063009D0043006E003D>-289<000300D2007B00680062004300D0>-291<000300E50077>]TJ
ET
EMC 

与第 16 页的说明相反,这里的 x 坐标是 40.0148,这显然在 CropBox 第 17 页。


注意:上面我说的那些文本矩阵设置指令的第五个条目(Tm)本质上是x 以下文本绘制指令将从左到右绘制文本的坐标。 这里的坐标是 当前 用户 space坐标.

如果之前有cm指令,则当前用户space坐标不是一定是默认用户space定义裁剪框的坐标

不过,对于您的文档,在上述说明之前没有使用 cm 说明。