首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android上的PDFBox文本抽取连接"fi“、"fl”问题

Android上的PDFBox文本抽取连接"fi“、"fl”问题
EN

Stack Overflow用户
提问于 2020-05-05 18:45:57
回答 2查看 660关注 0票数 3

我正在使用Android库上的https://github.com/TomRoush/PdfBox-Android PDFBox从一个PDF文档中提取文本。我正在做的事情是:

代码语言:javascript
复制
File pdf_file = new File(file_path);

若要创建该文件,则

代码语言:javascript
复制
PDDocument document = null;
document = PDDocument.load(pdf_file);

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

代码语言:javascript
复制
PDFTextStripper pdfStripper = new PDFTextStripper();
pdfStripper.setStartPage(...);
pdfStripper.setEndPage(...);
String page_text = pdfStripper.getText(document);

若要获取页面的文本内容,请执行以下操作。问题是,例如,当有“坚定”一词时,它就像"fi rm“一样显示出来。它基本上在fi之后放了一个空格(我猜fls和其他连接线)。我试着读了这个使用OpenTypeFont提取pdfBox文本的问题,但是我不知道如何修复它。没有解决方案的细节。

重要:事实证明,在我的PDF文件中,我没有像fi这样的连接,但是我有普通的fi,但是在它之后还有空间。解决方案尚不清楚。

PDF文件:https://wetransfer.com/downloads/09e9036dda4a7962ccad32b1cbcd8edc20200506050349/ab4752

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-05-11 15:06:18

问题是,例如,当有“坚定”一词时,它就像"fi rm“一样显示出来。

原因很简单:后面的一个空格!

这是文本绘图指令,在您的示例文件中第一次出现“事务所”:

代码语言:javascript
复制
 [( )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带有文本行的复制和粘贴摘录

代码语言:javascript
复制
Mr Dursley was the director of a fi rm called Grunnings,

就像PDFBox一样,它扩展了连接并提取了空间字符。

票数 5
EN

Stack Overflow用户

发布于 2020-05-06 11:22:56

正如评论中提到的,有一次我也遇到了一个类似的问题。我不得不检查某些字符串的PDF文件,并想知道为什么它对某些字符串无效。经过分析,我发现这些文件包含连接,因此我无法找到"Textfield“,即使它在视觉上包含它。我的解决方案是不仅搜索textfield,而且搜索textfield --所以搜索两个字符串,一个字符串带有和一个没有连接。

你说你想从pdf文件中提取文本。因此,我会添加一个后处理步骤。

  1. 像现在一样提取文本
  2. 搜索所有连接,例如"fi“和"fi”,并将其替换为"fi“。

我在结扎后没有任何空间的文件-所以我会考虑这两种情况。此外,还应考虑词尾(如buffi)的情况(可能是两个空格?)。

一个笼统的词:这个话题并不容易,因为你已经研究过了。这个步骤称为NFKC规范化。在pdfbox 2.X中,这是在内部完成的(cp。PDFBOX-2384),但在pdfbox 1.X中,TextNormalize.java是做这事

Upate:

您可以尝试的另一种可能性是更改PDFTextStripper.java。有一个叫做normalizeWord(...)的方法。它将单一的"fi“连接转换为"f”和"i“。你可以在这里加上

代码语言:javascript
复制
//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)。好的是,只有在找到结扎的时候才能使用。然而,这似乎不是一个普遍的解决办法,因为问题的词,结束了一个捆绑。但在你的情况下,你应该是好的,因为始终有一个空间后,每次结扎。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61620666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档