使用 PDFBox 匹配从 PDF 解析的文本

Matching text parsed from a PDF with PDFBox

这与其说是一个问题,不如说是一种学习。我最近正在努力匹配使用 PDFBox 从 PDF 中解析出的字符串。我的解决方案可能对其他人有帮助

文本列表是使用 PDFBox 从 PDF 中获取的(为简洁起见省略了例外):

List<String> lines = new ArrayList<String>();
PDDocument document = PDDocument.load(f);
PDFTextStripper pdfStripper = new PDFTextStripper();
String text = pdfStripper.getText(document);
String[] pageText = text.trim().split(pdfStripper.getLineSeparator());
for (String line : pageText) {
        lines.add(line);
}

列表现在按顺序包含文件中的所有行。

但是,String.contains 和 String.equals 在日志中看似相同的行上失败(即:'EMERA INCORPORATED')。在将每个字符转换为十六进制时,很明显 Space 字符是问题所在:

Line (Parsed from PDF with PDF Box): EMERA INCORPORATED
45 4d 45 52 41 a0 49 4e 43 4f 52 50 4f 52 41 54 45 44

CompanyName (Set In Java): EMERA INCORPORATED
45 4d 45 52 41 20 49 4e 43 4f 52 50 4f 52 41 54 45 44

注意 PDFBox 字符串中的 'a0',其中 Java 中有 space ('20')。

解决方案是使用正则表达式来识别行:EMERA\S+INCORPORATED。这为匹配提供了更好的控制器,所以它还不错。但是弄清楚这一点有点烦人,因为在查看日志时,被比较的字符串看起来相同,但 contains 和 equals 都返回 false。

我的结论是,使用 RegEx 识别来自 PDF 的文本模式(使用 PDFBox 获得)并确保添加 '\S' 来表示潜在的 spaces。也许这个 post 可以减轻一些人的痛苦。此外,如果这是我的用户错误,也许更熟悉 PDFBox 的人可以提供更好地使用 API 的提示。

perhaps someone more familiar with PDFBox could provide tips on using the API better if this is user error on my part

在 PDFBox API 用法 中不是错误。它 不是 甚至 特定于 PDFBox。更多的是错误的期望

不同种类的 space 个字符

首先,有不同种类的space个字符。当然还有最常用的Unicode Character 'SPACE' (U+0020) but there also are others, in particular the Unicode Character 'NO-BREAK SPACE' (U+00A0).

因此,如果您不知道在给定文本中只使用了一个特定的 space 字符,则使用带有“\S”而不是“”的正则表达式是完全正常的。

PDFBox提取什么?

在手头的情况下,使用非中断 space 甚至没有通过选择 PDFBox 使用。相反,它在 PDF 中根深蒂固。

从 PDF 中提取文本时,PDFBox(就像其他 PDF 库一样)使用 PDF 内部的信息,了解哪个字形代表哪个 Unicode 字符。此信息可以通过 PDF 中相应字体声明的 Encoding 条目或 ToUnicode 条目提供。

仅当两个文本块之间存在间隙时(自由 space 不是通过绘制 space 字符而是通过移动没有文本字符的文本插入点创建的),PDF 文本提取器添加他们各自选择的 space 字符,通常是常规的 space.

由于 PDFBox 在后一种情况下确实使用了常规 space,目前的问题是第一种情况的情况,PDF 本身表明 space 有一个非破坏性的.