我需要解析PDF文档。我已经实现了解析器并使用了库 iText ,直到现在它没有任何问题。
但是我不需要解析另一个在单词中间会得到非常奇怪的空格的文档。例如,我得到:
Vo rber eitung auf die Motorr adsaison 。 Viele Motorr adf ahr er
所有大胆的单词都应该连接,但不知何故,PDF Parser会在单词中添加空格。但是当我将PDF中的内容复制并粘贴到文本文件中时,我得不到这些空格。
首先我认为这是因为我正在使用的PDF解析库,但是对于另一个库,我得到了完全相同的问题。
我从解析过的单词中查看了singleSpaceWidth
,我发现当它添加一个空格时,它总是变化的。我试图将它们手动放在一起。但是,由于没有真正重新组合单词的模式,这几乎是不可能的。
其他人是否有类似的问题甚至解决了这个问题?
根据要求,这里有更多信息:
使用SemTextExtractionStrategy进行解析:
PdfReader reader = new PdfReader("data/SpecialTests/SuedostSchweiz/" + src);
SemTextExtractionStrategy semTextExtractionStrategy = new SemTextExtractionStrategy();
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
// Set the page number on the strategy. Is used in the Parsing strategies.
semTextExtractionStrategy.pageNumber = i;
// Parse text from page
PdfTextExtractor.getTextFromPage(reader, i, semTextExtractionStrategy);
}
这里实际解析文本的SemTextExtractionStrategy方法。我在每个解析的单词之后手动添加一个空格,但不知何故它确实在检测中分割了单词:
@Override
public void parseText(TextRenderInfo renderInfo, int pageNumber) {
this.pageNumber = pageNumber;
String text = renderInfo.getText();
currTextBlock.getText().append(text + " ");
....
}
这是整个SemTextExtraction类,但在那里它只调用上面的方法(parseText):
public class SemTextExtractionStrategy implements TextExtractionStrategy {
// Text Extraction Strategies
public ColumnDetecter columnDetecter = new ColumnDetecter();
// Image Extraction Strategies
public ImageRetriever imageRetriever = new ImageRetriever();
public int pageNumber = -1;
public ArrayList<TextParsingStrategy> textParsingStrategies = new ArrayList<TextParsingStrategy>();
public ArrayList<ImageParsingStrategy> imageParsingStrategies = new ArrayList<ImageParsingStrategy>();
public SemTextExtractionStrategy() {
// Add all text parsing strategies which are later on applied on the extracted text
// textParsingStrategies.add(fontSizeMatcher);
textParsingStrategies.add(columnDetecter);
// Add all image parsing strategies which are later on applied on the extracted text
imageParsingStrategies.add(imageRetriever);
}
@Override
public void beginTextBlock() {
}
@Override
public void renderText(TextRenderInfo renderInfo) {
// TEXT PARSING
for(TextParsingStrategy strategy : textParsingStrategies) {
strategy.parseText(renderInfo, pageNumber);
}
}
@Override
public void endTextBlock() {
}
@Override
public void renderImage(ImageRenderInfo renderInfo) {
for(ImageParsingStrategy strategy : imageParsingStrategies) {
strategy.parseImage(renderInfo);
}
}
}
答案 0 :(得分:3)
我使用以下Ghostscript命令处理了给定的PDF文件:
gs -o out.pdf -q -sDEVICE=pdfwrite -dOptimize=false -dUseFlageCompression=false -dCompressPages=false -dCompressFonts=false whitespacesProblem.pdf
此命令创建了一个文件out.pdf
,它没有流编码,因此更易读。有趣的部分是在第52行,为了便于阅读,我将其拆分为多行:
[
(&;&)-287.988
(672744)29.9906
(+\(%)30.01
(+!4)29.9876
(&4)-287.989
(%4)30.0039
(&1&8)-287.975
(3=\)!)-288.021
(*&4)30.0212
(&=23)-287.996
(+1%)-287.99
(\(=&)-288.011
(8&1&)-287.974
(672744)29.9906
(+\(3+=378$)-250.977
(#7\)!)
]TJ
括号之间是文本字符。我更改了其中一些并观看了渲染的PDF文件,以查看哪个字符代表哪个字形。然后我解码了文本:
[
(ele)-287.988
(Motorr)29.9906 ***
(adf)30.01 ***
(ahr)29.9876 ***
(er)-287.989
(fr)30.0039
(euen)-287.975
(sich)-288.021
...
]
所以角色之间确实有空白。在你的情况下,这可能是字体的字距。现在的问题是你的PDF库如何解释这个空格,在我看来,即使是“负空白”也会被渲染到结果字符串中的空格中。
答案 1 :(得分:2)
pdf中的空白是一个已知的问题,正如Roland在这里的回答所描述的那样,并且在第一个评论中也看到了 https://issues.apache.org/jira/browse/TIKA-724
对我来说也是有用的答案就是huuhungus所看到的那个 https://github.com/smalot/pdfparser/issues/72
特定于PDFParser,如果您知道会遇到此问题,则更改实际将此额外空间添加到PDFParser的代码:
src / Smalot / PdfParser / Object.php注释掉这一行
$text .= ' ';
没有完全解决它,但它是可接受的
其他库也可能有类似的临时修复,因此在某些情况下他们可以帮助解决此问题。
答案 2 :(得分:0)
因为您拥有的文档被拆分为列,所以明显的错误在
中SemTextExtractionStrategy
类。我假设类 ColumnDetecter 可能被指责,而不是iText。我只能假设它是根据列的大小实现的,然后根据它检索文本。
如果您只想要文本,那么根据列的大小,实现可能会更简单。