通过正则表达式将页面区分为pdf流

时间:2012-10-02 09:14:49

标签: regex pdf

我需要从pdf流中提取一些信息。
提取相关文本非常简单,因为它类似于:

BT /Fo0 7.20 Tf 67.81 569.38 Td 0.000 Tc (TOTAL AMOUNT) Tj ET

我可以考虑修正y位置,而x位置由于giustification而变化。 但我的问题是识别页面的开头及其结束。

1 个答案:

答案 0 :(得分:2)

您不应该确定与“信息提取器”相关的所有PDF都表现得非常好。或者你可以,因为你知道他们是谁?

否则,您遇到的PDF代码很可能会发生:

BT 
  /Fo0 7.20 Tf 
  67.81 569.38 Td 
  0.000 Tc 
  (TO)12(T)13(AL A)11(M)14(OUNT) TJ 
ET

即......

  • ...使用TJ代替Tj,以允许个性字形定位,
  • ......有更多的换行符,
  • ......也许还有更多的修改。

为了可靠地获取页面的文本内容,您必须解析PDF的结构,简而言之:

  1. 找到/Type /Page;
  2. 的所有对象
  3. 转到每个页面对象,并检索有关其/Contents的信息;
    • /Contents可能指向单个流,或
    • /Contents可能指向一组流;
  4. 转到此内容对象并提取其流。
  5. 实际上,上述第一步可能会变得更复杂:

    • 找到并转到trailer <<...>>部分
    • 预告片中的
    • 找到有关文档/Root对象
    • 的信息
    • 转到根对象
    • /Pages对象
    • 中提取有关/Root的信息
    • 转到/Pages对象(与孩子和父母一起的intermedia 页面树节点;
    • 从检查/Kids对象
    • 中查找此页面树节点的所有后代
    • 转到/Kids列出的各个对象;
      • 它可能是/Type /Pages(在这种情况下,它是另一个页面树节点,而不是树 leaf ,你必须遵循树进一步);
      • 它可能是/Type Page(在这种情况下,您到达了一个页面树 leaf ,这意味着您真的到达了一个页面。)

    此时我应该注意,您在此旅程后找到的第一页是第1页。接下来是第2页等。请注意,没有任何页面有任何元数据说“我是页码N” - 这完全取决于您从根对象中解析页面树的顺序。

    既然您确实找到了内容流,那么您将面临另外两个问题:

    1. 您正在寻找的内容流可能根本不是明文(如您的代码所示)。内容流经常被允许的压缩方案之一压缩,在解析文本内容之前,您必须先扩展它们。

      要查看流是否已压缩,请注意相应的 * Decode 关键字(经常显示为/Filter /FlateDecode)。

    2. 成功解压缩网页的内容流后,您可能会遇到描述文字的完全不直观的字符代码。它可能根本不是您想象并在示例代码中显示的相同类型的良好行为ASCII。

      你必须查找字体(甚至像CID这样的多字节字体),它们的编码,CMaps和什么不是。

      除非我在最初的句子中提出质疑,否则知道在您的特定用例中没有发生......