使用iTextSharp,我试图从以下pdf文件中提取文本:
https://www.treasury.gov/ofac/downloads/sdnlist.pdf
这是代码:
var currentText = PdfTextExtractor.GetTextFromPage(pdfReader, 2, new SimpleTextExtractionStrategy());
if (currentText.Length > 0)
{
var capture = new Capture();
capture.Text = currentText;
// write the results to the DB, if any data was found
_dataService.AddCapture(capture);
}使用SimpleTextExtractionStrategy,结果被写到数据库中,在单词中有无数不需要的空格。第2页的前几行写成:
外国资产管制办公室特别指定的国民和被封锁者2017年2月3日-2-A.A. .k。a. AL MAZ -AN TEY MSDB;a .k.a .AL MAZ -ANTEY PV O 'AI R国防‘CO主导系统M S设计局OAO’开放JO INT -STOCK公司‘IMENI学术伊恩A.A。RASPLETIN;a.k . .a.OYE KONS TRUKT ORSKOY BYURO OIN TIN TOCK C OMP ALMAZ -AN TEY PVO ONCERN I MEN I J .A.a. JO股票C OMPANY A LMA Z-和泰伊AI R防御CON CERN MA在系统M设计局命名为ACADE MICIAN A.A.
例如,参见第4行和第6行中的"JO INT“,以及第2至最后一行中的"CON CERN”。这些类型的空间在整个结果中都会出现。不幸的是,这将使查询文本变得不可能。
有没有人知道为什么这样做,以及如何解决这个问题?
发布于 2017-02-07 09:43:10
为什么会这样
其原因实际上是文本提取策略的一个特性,而在您的情况下,该策略不按需要工作。
背景:您认为PDF文件中单词之间的空格并不一定是由于指令绘制空格字符而产生的,它也可能是指令将文本插入位置稍微向右移动的结果。因此,当发现足够大的右移时,文本提取策略通常会添加一个空格字符。对于更多关于这一点(特别是“足够大”部分)的讨论,请参见这个答案。
但是,在文档中,文本正文字体的字体宽度信息太小(如果按原样使用,字符似乎粘合在一起,没有空格--在任何字符之间);因此,每两个连续字符之间都会有小的右移,其中一些移动的范围足够宽,可以通过上面解释的机制错误地识别为单词分隔。
如何解决这个问题
由于PDF中的单词分隔是由绘制空格字符的指令创建的,因此不需要上面解释的特性。因此,解决该问题的最简单方法是使用没有该功能的文本提取策略。
您可以通过复制SimpleTextExtractionStrategy的源代码(例如来自这里)并注释掉方法RenderText中的一些行来创建这样的策略,如下所示:
public virtual void RenderText(TextRenderInfo renderInfo)
{
[...]
if (hardReturn)
{
//System.out.Println("<< Hard Return >>");
AppendTextChunk('\n');
}
else if (!firstRender)
{
// if (result[result.Length - 1] != ' ' && renderInfo.GetText().Length > 0 && renderInfo.GetText()[0] != ' ')
// { // we only insert a blank space if the trailing character of the previous string wasn't a space, and the leading character of the current string isn't a space
// float spacing = lastEnd.Subtract(start).Length;
// if (spacing > renderInfo.GetSingleSpaceWidth() / 2f)
// {
// AppendTextChunk(' ');
// //System.out.Println("Inserting implied space before '" + renderInfo.GetText() + "'");
// }
// }
}
else
{
//System.out.Println("Displaying first string of content '" + text + "' :: x1 = " + x1);
}
[...]
}使用这种简化的提取策略,您的文本将被正确提取。
https://stackoverflow.com/questions/42073700
复制相似问题