加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何使用带空格的itextsharp从pdf中提取文本?

发布时间:2020-12-16 00:22:58 所属栏目:百科 来源:网络整理
导读:我正在使用以下方法逐行提取pdf文本.但问题是,它不是在文字和数字之间阅读空格.什么可以解决这个问题? 我只想创建一个字符串列表,列表对象中的每个字符串都有一个来自pdf的文本行,因为它在pdf中包含空格. public void readtextlinebyline(string filename)
我正在使用以下方法逐行提取pdf文本.但问题是,它不是在文字和数字之间阅读空格.什么可以解决这个问题?

我只想创建一个字符串列表,列表对象中的每个字符串都有一个来自pdf的文本行,因为它在pdf中包含空格.

public void readtextlinebyline(string filename)   {


        List<string> strlist = new List<string>();
        PdfReader reader = new PdfReader(filename);
        string text = string.Empty;
        for (int page = 1; page <= 1; page++)
        {

            text += PdfTextExtractor.GetTextFromPage(reader,page,new LocationTextExtractionStrategy())+" ";

        }
        reader.Close();
        string[] words = text.Split('n');
        foreach (string word in words)
        {
            strlist.Add(word);
        }

        foreach (string st in strlist)
        {
            Response.Write(st +"<br/>");
        }

   }

我已经通过将策略更改为SimpleTextExtractionStrategy来尝试此方法,但它也不适用于我.

解决方法

关于为什么单词之间的空格有时未被iText(夏普)或其他PDF文本提取器正确识别的背景已在 this answer to “itext java pdf to text creation”中解释:这些“空格”不一定使用空格字符创建,而是使用创建小间隙的操作.但是,这些操作也用于其他目的(不会破坏单词),因此文本提取器必须使用启发式方法来判断这样的间隙是否是单词中断…

这尤其意味着您永远不会获得100%安全的断字检测.

但是,您可以做的是改进所使用的启发式方法.

iText和iTextSharp标准文本提取策略,例如假设一行中断了一个单词

a)有空格字符或

b)存在至少与半个空格字符一样宽的间隙.

项目a肯定会被击中,但是在密集设置文本的情况下,项目b可能经常失败.对于answer referenced above的问题的OP使用空格字符的宽度的四分之一而得到了相当好的结果.

您可以通过复制和更改所选的文本提取策略来调整这些条件.

在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期间,遗憾的是没有虚拟添加到声明中(从版本5.4.4开始).因此,iTextSharp目前仍然需要复制整个策略.

@Bruno你可能想告诉iText – >关于此,iTextSharp移植团队.

虽然您可以在这些代码位置微调文本提取,但您应该知道在这里找不到100%的标准.一些原因是:

>密集设置文本中的单词之间的间隙可能比单词内部的某些光学效果的字距调整或其他间隙小.因此,这里没有一个通用的因素.
>在完全没有使用空格字符的PDF中(因为你总是可以使用间隙,这是可能的),“空格字符的宽度”可能是一些随机值或根本无法确定!
>有一些有趣的PDF滥用空格字符宽度(可以随时单独拉伸以便操作跟随)在使用间隙进行分词时进行一些表格格式化.在这样的PDF中,空格字符的当前宽度的值不能严重地用于确定单词中断.
>有时候你会发现一条印在一条线上的单词以便强调.这些可能会被大多数启发式解析为单字母单词的集合.

通过考虑所有角色之间的实际视觉自由空间(使用PDF渲染或字体信息分析机制),您可以获得比iText启发式更好的功能以及使用其他常量得出的功能,但是为了实现可感知的改进,您必须投入大量时间.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读