PDFBox在Android Studio上提取文本连接符 "fi"、"fl "的问题。

问题描述 投票:1回答:1

我在用这个 https:/github.comTomRoushPdfBox-Android。 在Android Studio库中使用PDFBox从PDF文档中提取文本。我是这样做的。

File pdf_file = new File(file_path);

创建文件,然后

PDDocument document = null;
document = PDDocument.load(pdf_file);

将文件加载到PDDocument对象中,然后用

PDFTextStripper pdfStripper = new PDFTextStripper();
pdfStripper.setStartPage(...);
pdfStripper.setEndPage(...);
String page_text = pdfStripper.getText(document);

来获取页面的文本内容。问题是,当有 "公司 "这个词时,它显示为 "fi rm"。它基本上是在 fi 后面放了一个空格(我想还有 fls 和其他连接符)。我试着读了一下 使用pdfBox提取OpenTypeFont文本的问题。 但我不明白如何解决。没有解决的细节。

重要:事实证明,在我的PDF文件中,我没有任何连字符,如fi,但我有常规的fi,但后面还有空格。解决方法不清楚。

PDF文件。https:/wetransfer.comdownloads09e9036dda4a7962ccad32b1cbcd8edc20200506050349ab4752。

java android-studio pdfbox text-extraction
1个回答
4
投票

问题是,当有 "公司 "这个词时,它显示为 "fi rm"。

原因很简单。原因很简单: 在 "fi "后面加一个空格!

这是在你的样本文件中,用第一次出现的 "firm "来画线的文字绘图指令。

 [( )360.3(Mr Dursley was the director of a “)250( )110.3(rm called Grunnings, )]TJ

字节 (147)通过字体编码映射到字形名上 fi 并借助 ToUnicode 字体与Unicode字符U+fb01的映射,即拉丁文的小引号fi。

因此,PDF查看器显示的连接字形为 和文本提取器提取Unicode连接字符。 或扩展后的字符 fi.

在这个连接点之后,绘制下一个字形的起始点被左移了250个单位,然后绘制了一个空格,然后下一个起始点被左移了110.3个单位,然后绘制了 "rm"。

因此,你在查看器中看不到 "fi "和 "rm "之间的空隙(因为向左移动抵消了空格字形的绘制),但文本提取器却提取了一个空格字符(因为它就在那里)。

你可以检查一下这是不是PDFBox的怪癖,例如Adobe Reader用复制&粘贴将那行文字提取为

Mr Dursley was the director of a fi rm called Grunnings,

就像PDFBox一样,它可以展开连接字符并提取空格字符。


2
投票

正如评论中提到的那样,我曾经遇到过类似的问题。我必须检查PDF文件中的某些字符串,我很奇怪为什么有些文件不能工作。经过分析,我发现这些文件包含了连接符,因此我找不到 "Textfield",即使它在视觉上包含了它。我的解决方案是不仅要搜索 textfield 但也为 textfield - 所以搜索两个字符串,一个有连接,一个没有连接。

你说你想从pdf文件中提取文本。所以我会增加一个后处理步骤。

  1. 像现在这样提取文本
  2. 搜索所有的连接符,例如 "fi "和 "fi",然后用 "fi "代替。

我有一些文件在连接符后面没有空格--所以我会考虑这两种情况。而词尾的情况(如buffi)也应该考虑(可能是两个空格呢?)。

总的来说:这个题目不容易,因为你已经研究过了。这一步叫做 NFKC正常化. 在pdfbox 2.X中,现在是在内部完成的(参见PDFBOX-2384),但在pdfbox 1.X中TextNormalize.java是 .

更新。

还有一种可能,你可以尝试修改PDFTextStripper.java。有一个方法叫做 normalizeWord(...). 它将单一的 "fi "连接符转换为 "f "和 "i"。你可以在这里添加

//line 1971...
//for PDFs where ligatures are followed by a space (e.g. "fi ve") 
if(word.substring(q+1,q+2).equals(" ")) {
  p = q + 2;
}
else {
  p = q + 1;
}

但我只用pdfbox 2.0.19试了一下(看来你用的是1.8.X)。好处是它只适用于发现连接符的情况。然而,它似乎并不是一个通用的解决方案,因为有问题的词是以连接符结尾的。但是在你的情况下,你应该可以解决,因为每个连接符后面似乎都有一个空格。

© www.soinside.com 2019 - 2024. All rights reserved.