iText PDFSweep RegexBasedCleanupStrategy в некоторых случаях не работает - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь использовать iText PDFSweep RegexBasedCleanupStrategy для редактирования некоторых слов из pdf, однако я хочу только отредактировать слово, но не появиться в другом слове, например.Я хочу редактировать «al» как отдельное слово, но я не хочу редактировать «al» в «минерале».Поэтому я добавляю границу слова ("\ b") в Regex в качестве параметра для RegexBasedCleanupStrategy,

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

, однако pdfAutoSweep.cleanUp не работает, если слово находится в конце строки.

1 Ответ

0 голосов
/ 08 октября 2018

Короче говоря

Причина этой проблемы заключается в том, что подпрограмма, которая объединяет извлеченные фрагменты текста в один String для применения регулярного выражения, не вставляет ни одного индикатора для разрыва строки.Таким образом, в этом String за последней буквой из одной строки сразу же следует первая буква следующей, которая скрывает границу слова.Поведение можно исправить, добавив соответствующий символ к String в случае разрыва строки.

Проблемный код

Подпрограмма, которая объединяет извлеченные фрагменты текста в один String это CharacterRenderInfo.mapString(List<CharacterRenderInfo>) в упаковке com.itextpdf.kernel.pdf.canvas.parser.listener.В случае просто горизонтального разрыва эта подпрограмма вставляет символ пробела, но в случае вертикального смещения, то есть разрыва строки, она не добавляет ничего дополнительного к StringBuilder, в котором генерируется представление String:

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.

...