【问题标题】:iText PDFSweep RegexBasedCleanupStrategy not work in some caseiText PDFSweep RegexBasedCleanupStrategy 在某些情况下不起作用
【发布时间】:2019-03-09 04:17:09
【问题描述】:

我正在尝试使用 iText PDFSweep RegexBasedCleanupStrategy 来编辑 pdf 中的一些单词,但是我只想编辑该单词而不是出现在其他单词中,例如。 我想将“al”编辑为单个单词,但我不想编辑“矿物”中的“al”。 所以我在 Regex 中添加单词边界(“\b”)作为 RegexBasedCleanupStrategy 的参数,

  new RegexBasedCleanupStrategy("\\bal\\b")

但是,如果单词位于行尾,则 pdfAutoSweep.cleanUp 不起作用。

【问题讨论】:

  • A 你声称然而 pdfAutoSweep.cleanUp 不起作用 - 你的意思是什么? cleanUp 根本不在那里编辑吗?还是它编辑了错误的东西? B 问题可能是正则表达式解释的问题。因此,我建议您添加标签regex
  • 我的意思是当单词在行尾时,清理没有编辑任何内容。如果我要编辑的单词是行的中间,清理会正确地编辑它。
  • 好的,我确实可以轻松重现该问题。

标签: itext itext7 redaction


【解决方案1】:

总之

此问题的原因是,将提取的文本块展平为单个 String 以应用正则表达式的例程没有插入任何换行符指示符。因此,在String 中,一行的最后一个字母紧随其后的是下一行的第一个字母,它隐藏了单词边界。如果出现换行符,可以通过向String 添加适当的字符来修复此行为。

有问题的代码

将提取的文本块扁平化为单个String 的例程是包com.itextpdf.kernel.pdf.canvas.parser.listener 中的CharacterRenderInfo.mapString(List<CharacterRenderInfo>)。如果只是水平间隙,此例程会插入一个空格字符,但如果是垂直偏移,即换行符,它不会向生成 String 表示的 StringBuilder 添加任何额外内容:

if (chunk.sameLine(lastChunk)) {
    // 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
    if (chunk.getLocation().isAtWordBoundary(lastChunk.getLocation()) && !chunk.getText().startsWith(" ") && !chunk.getText().endsWith(" ")) {
        sb.append(' ');
    }
    indexMap.put(sb.length(), i);
    sb.append(chunk.getText());
} else {
    indexMap.put(sb.length(), i);
    sb.append(chunk.getText());
}

一个可能的解决办法

可以扩展上面的代码以在换行的情况下插入换行符:

if (chunk.sameLine(lastChunk)) {
    // 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
    if (chunk.getLocation().isAtWordBoundary(lastChunk.getLocation()) && !chunk.getText().startsWith(" ") && !chunk.getText().endsWith(" ")) {
        sb.append(' ');
    }
    indexMap.put(sb.length(), i);
    sb.append(chunk.getText());
} else {
    sb.append('\n');
    indexMap.put(sb.length(), i);
    sb.append(chunk.getText());
}

CharacterRenderInfo.mapString 方法仅从RegexBasedLocationExtractionStrategy 方法getResultantLocations()(包com.itextpdf.kernel.pdf.canvas.parser.listener)调用,并且仅用于提到的任务,即应用有问题的正则表达式。因此,使其能够正确识别单词边界不应该破坏任何东西,但确实应该被视为一种修复。

人们可能只考虑为换行符添加不同的字符,例如一个普通的空间' ',如果不想处理与水平间隙不同的垂直间隙。因此,对于一般修复,可以考虑将此字符作为策略的可设置属性。

版本

我使用 iText 7.1.4-SNAPSHOT 和 PDFSweep 2.0.3-SNAPSHOT 进行了测试。

【讨论】:

  • 嗨,mkl,这个补丁在 7.1.5 快照中吗?
  • 补丁适用于这个问题;一点进一步的信息,看起来它也与转换的pdf有关,我使用wkhtmltopdf将一个html转换为pdf,出现问题,但是如果我使用其他软件转换,没有问题。
  • “它也与转换后的 pdf 有关” - 很可能,一些生成器在行尾显式地绘制了一个空格字符,而另一些则没有。如果存在这样的空格字符,则原始 itext 代码已经与行尾的单词边界匹配。
猜你喜欢
  • 2018-11-28
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-17
  • 2017-06-29
  • 1970-01-01
相关资源
最近更新 更多