首页 > 解决方案 > 如何编辑以十六进制格式编码的 pdf 文本?

问题描述

我正在尝试查找某些文本并将其替换为 PDF 中的特定值。我正在使用 python 库pdfrw,因为我的首选环境是 python。以下是文档第一页中的示例内容。

BT\n/F8 40 Tf\n1 0 0 -1 569 376 Tm\n<0034> Tj\n26 0 Td <0028> Tj\n22 0 Td <0032> Tj\n25 0 Td <0031> Tj\n32 0 Td <0034> Tj\n26 0 Td <0036> Tj\nET\n0 .8863 1 RG

它对应于文档中的“报告”一词。到目前为止,我已经理解了这种格式的所有特殊标签和数字的含义,并成功地操纵了其中的位置和一些字符。但我不明白每个字符的编码格式或编码(<0034>、<0028> 等)。

我尝试暴力破解 <00xx> 的每一个组合,但只找到了字母 R、E、P、O、T 的有效匹配,这些字母是单词中使用的字母。我对页面中包含的 F11 和 F10 进行了相同的尝试,并在匹配仅使用的字母时发现了相同的结果。如果有人能解释这种编码是如何工作的,以及我如何编辑它以便能够插入任何 utf-8 字符,那将非常有帮助。

谢谢你。

注1:以下是F8对象:

{'/Subtype': '/Type0', '/Type': '/Font', '/BaseFont': '/OpenSans-Bold', '/Encoding': '/Identity-H', '/DescendantFonts': [{'/DW': '0', '/Subtype': '/CIDFontType2', '/CIDSystemInfo': {'/Supplement': '0', '/Registry': '(Adobe)', '/Ordering ': '(Identity)'}, '/Type': '/Font', '/FontDescriptor': {'/Descent': '-292.96875', '/CapHeight': '713.86719', '/StemV': ' 83.984375', '/Type': '/FontDescriptor', '/FontFile2': {'/Length1': '5540', '/Length': '5540'}, '/Flags': '4', '/FontName ': '/OpenSans-Bold', '/ItalicAngle': '0', '/FontBBox': ['-619.14063', '-292.96875', '1318.84766', '1068.84766'], '/Ascent': '1068.84766'}, '/BaseFont': '/OpenSans-Bold', '/W' : ['0', ['600.09766'], '40', ['560.05859'], '49', ['795.89844', '627.92969', '0', '660.15625', '0', '579.10156' ]], '/CIDToGIDMap': '/Identity'}], '/ToUnicode': {'/Length': '413'}}0', '660.15625', '0', '579.10156']], '/CIDToGIDMap': '/Identity'}], '/ToUnicode': {'/Length': '413'}}0', '660.15625', '0', '579.10156']], '/CIDToGIDMap': '/Identity'}], '/ToUnicode': {'/Length': '413'}}

注意 2:在 (nice text)Tj\n 或 (<0032><0032>) 方式中替换文本在这里也不起作用。

标签: pythonpdftextpdf-generationtext-processing

解决方案


因此,正如先前的答案所指出的那样,文档中的嵌入字体只是一个子集,并且编码引用了我不知道的字符。我通过首先创建包含字母表中每个字母(包含我需要的字体信息)的临时 pdf 并将原始文件的资源字体替换为我的新文件的资源字体来解决了这个问题。然后我可以像这样轻松地以与我的临时文件相同的方式操作文本

target.pages[0].Resources.Font=font_pdf.pages[0].Resources.Font
target.pages[0].Contents.stream.replace(
    "BT\n/F8 40 Tf\n1 0 0 -1 569 376 Tm\n<0034> Tj\n26 0 Td <0028> Tj\nET", 
    f"BT\n/F0 11 Tf\n1 0 0 -1 500 500 Tm\n(\x02Y\x02Q) Tj\nET"
)

谢谢你们 :)

注意:我仍然没有使用自己的字体解码十六进制的好的解决方案。所以我决定使用模式匹配,因为我知道应该期待什么文本。更好的解决方案将非常有帮助


推荐阅读