为什么的话,有时不能正常通过的iText(夏普),或者其他的PDF文本提取的认可之间的空间,已经在this answer to "itext java pdf to text creation"解释的背景:这些“空间”不必使用空格字符创建而是使用创建一个小差距的操作。这些操作也用于其他目的(不会打破单词),所以文本提取器必须使用启发式方法来确定这种间隔是否是分词符或不是...
这特别意味着您从来没有得到100%安全的分词检测。
虽然你可以做的是改善启发式。
iText和iTextSharp标准文本提取策略,例如,假设在一个线的字断如果
一个)有一个空格字符或
b)中有作为半空格字符的间隙至少宽。
项目a确实是命中,但项目b在密集设置文本的情况下可能经常失败。问题的OP到answer referenced above用空格字符的宽度的四分之一取得了相当好的结果。
您可以通过复制和更改您选择的文本提取策略来调整这些标准。
在SimpleTextExtractionStrategy
你觉得这个标准嵌入renderText
方法:
if (spacing > renderInfo.GetSingleSpaceWidth()/2f){
AppendTextChunk(' ');
}
在LocationTextExtractionStrategy
的情况下,该标准同时已投入了自己的方法:
/**
* Determines if a space character should be inserted between a previous chunk and the current chunk.
* This method is exposed as a callback so subclasses can fine tune the algorithm for determining whether a space should be inserted or not.
* By default, this method will insert a space if the there is a gap of more than half the font space character width between the end of the
* previous chunk and the beginning of the current chunk. It will also indicate that a space is needed if the starting point of the new chunk
* appears *before* the end of the previous chunk (i.e. overlapping text).
* @param chunk the new chunk being evaluated
* @param previousChunk the chunk that appeared immediately before the current chunk
* @return true if the two chunks represent different words (i.e. should have a space between them). False otherwise.
*/
protected bool IsChunkAtWordBoundary(TextChunk chunk, TextChunk previousChunk) {
float dist = chunk.DistanceFromEndOf(previousChunk);
if(dist < -chunk.CharSpaceWidth || dist > chunk.CharSpaceWidth/2.0f)
return true;
return false;
}
的将其纳入其自身方法的意图仅仅是要求对策略进行简单的子类别划分,并重写此方法来调整启发式标准。这适用于等效的iText Java类的情况,但在iTextSharp的端口中很不幸,没有virtual
已被添加到声明中(从版本5.4.4开始)。因此,iTextSharp仍然需要复制整个策略。
@布鲁诺你可能想告诉iText - > iTextSharp移植团队这件事。
虽然您可以在这些代码位置上对文本提取进行微调,但您应该知道在这里不会找到100%的条件。原因如下:
- 密集设置的文本中的单词之间的间隙可能小于字距内的某些光学效应的字距或其他间隔。因此,这里没有一刀切的因素。
- 在PDF中根本不使用空格字符(因为您始终可以使用空格,这是可能的),“空格字符的宽度”可能是一些随机值或根本无法确定!
- 有些有趣的PDF滥用空格字符宽度(可随时单独拉伸以供操作遵循),以在使用空格打破分词时执行一些表格格式。在这样的PDF中,空格字符的当前宽度的值不能被严重用于确定分词符。
- 有时,您会发现一行中的单词在打印间隔为强调。这些可能会被大多数启发式算法解析为一个字母单词的集合。
你可以得到比iText的启发,更好地那些使用其他常量考虑到实际的视觉自由空间中的所有字符之间(使用PDF渲染或字体信息分析机制)它衍生出来的,但对于一个感知的改进你必须投入很多时间。
来源
2013-11-18 14:09:21
mkl
这[回答 “iText的java的PDF文本创建”](http://stackoverflow.com/questions/13644419/itext-java-pdf-to-text-creation/13645183#13645183)可以示出一个解决方案的原因和提示:复制文本extration策略并调整内部参数,在您的情况下,默认情况下将缺口的最小宽度识别为空格'renderInfo.getSingleSpaceWidth()/ 2f';使用'renderInfo.getSingleSpaceWidth()/ 4f'来回询问的人得到了改进的结果。 – mkl 2013-05-06 13:25:48
@Pengu当你提供赏金时,你肯定会遇到这个问题。因此,您当然可以提供一个或多个样本PDF以作为提议解决方案的测试用例。这个问题的当前状态回答了纯粹的猜测。 – mkl 2013-11-11 16:19:46
@mkl对于迟到的回复,我的连接断了,我很抱歉。我不喜欢的不是你的解决方案(它的工作原理) - 有什么不满的是,这个解决方案可能不可靠。 F.E:它可以与一个文件一起使用,但也可能在另一个文件中产生太多空格(原因是文档需要renderInfo.getSingleSpaceWidth()/ 2f或完全不同的分隔符)。我没有一个例子,但它的某些我可以想象它会发生。所以我要求一个“更多”可靠来源的答案。 – BudBrot 2013-11-18 07:53:20