【问题标题】:Parsing PDF file using Regular expressions in Python在 Python 中使用正则表达式解析 PDF 文件
【发布时间】:2011-04-24 07:52:56
【问题描述】:

我正在尝试使用 Python 的 re 模块从 PDF 文件中解析一些对象元素。我的目标是使用正则表达式解析每个 PDF 对象。 PDF 对象示例如下:

1 0 obj
<<
    /Type /Catalog
    /Pages 2 0 R
>>
endobj
2 0 obj
<<
    /Type /Pages
    /Kids [ 3 0 R ]
    /Count 1
>>
endobj
...

当我使用"\d+\s\d+\sobj[\s,\S]*endobj" 时它不起作用(它一直在解析 util 最后一个 endobj 被发现)。如何修改正则表达式以分别解析每个对象(换句话说,从 1 0 obj 到 endobj 的部分)?

【问题讨论】:

    标签: python regex parsing pdf


    【解决方案1】:

    如果您只使用正则表达式,则很容易构建您的程序无法处理的 PDF 文件。 PDF 字典和列表可以包含其他对象。正则表达式不能处理递归结构,至少 Python re 模块不能。

    pdf 文件是对象和流的树:

    • 字典:&lt;&lt;(名称值)* &gt;&gt;
    • 列表:[(值)* ]
    • 姓名:/(常规字符)*
    • 字符串:( (char)* )
    • 十六进制字符串:&lt; (hexchar)* &gt;
    • 号码:(-)? ((数字)+ | (数字)+ . (数字)* | . (数字)+)
    • 布尔值:true | false
    • 参考:(数字)+(空白)+(数字)+(空白)+R

    大多数地方都会忽略空格和 cmets。 评论以% 开头,一直到行尾。

    间接对象指定为:

    1 0 obj
    (any object)
    endobj
    

    然后可以将该对象引用为1 0 R。间接字典也可以附加一个流:

    1 0 obj
    <<
    /Length 22
    >>
    stream
    (22 bytes of raw data)
    endstream
    endobj
    

    PDF 文件如下所示:

    %PDF-1.4
    %ÿÿÿÿ
    1 0 obj
    << /Author (MizardX) >>
    endobj
    2 0 obj
    <<
    /Type /Catalog
    % more required keys
    >>
    endobj
    %lots of more indirect objects, one after another
    trailer
    <<
    /Info 1 0 R
    /Root 2 0 R
    % ... more required keys
    >>
    xref
    0 3
    0000000000 65535 f
    0000000015 00000 n
    0000000054 00000 n
    startxref
    225
    %%EOF
    

    对象树的根是trailer 对象。每个对象都直接或间接地从该字典中引用。

    流中隐藏着更多复杂性,但这不会影响文件结构。

    完整的规范可以在Adobe's website找到。

    【讨论】:

      【解决方案2】:

      您需要使用*?作为非贪婪版本 - 请参阅documentation here

      另外,请注意 PDF 格式非常复杂 - 尤其是当它开始在其中包含二进制流时 - 但如果您知道您正在查看的 PDF 很简单,那么这应该可以工作。

      【讨论】:

        【解决方案3】:

        重复部分后的问号应占用最少的字符。也不需要逗号,因为\S 已经考虑到了它。

        \d+\s\d+\sobj[\s\S]*?endobj
        

        【讨论】:

          【解决方案4】:

          不完全是您确切问题的答案,但您可能想查看 python 中现有的 pdf 解析库,例如:pdfminerpyPdf。 (即使你最终没有使用它们,你也不妨看看他们是如何做到的)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-05-18
            • 2014-05-16
            • 1970-01-01
            • 1970-01-01
            • 2021-02-15
            • 1970-01-01
            • 1970-01-01
            • 2010-10-23
            相关资源
            最近更新 更多