8

我有一堆 PDF 文件,我的 Perl 程序需要对它们进行全文搜索以返回哪些包含特定字符串。迄今为止,我一直在使用这个:

my @search_results = `grep -i -l \"$string\" *.pdf`;

其中 $string 是要查找的文本。然而,这对于大多数 pdf 文件来说都失败了,因为文件格式显然不是 ASCII。

我能做什么最简单?

澄清:大约有 300 个 pdf 的名称我事先不知道。PDF::Core 可能是矫枉过正。我试图让 pdftotext 和 grep 相互配合,因为我不知道 pdf 的名称,我还找不到正确的语法。

使用 Adam Bellaire 的以下建议的最终解决方案:

@search_results = `for i in \$( ls ); do pdftotext \$i - | grep --label="\$i" -i -l "$search_string"; done`;
4

6 回答 6

9

PerlMonks 线程在这里讨论了这个问题。

似乎对于您的情况,获取pdftotext(命令行工具)可能是最简单的,然后您可以执行以下操作:

my @search_results = `pdftotext myfile.pdf - | grep -i -l \"$string\"`;
于 2008-09-26T12:21:51.023 回答
3

我的库CAM::PDF支持提取文本,但考虑到 PDF 语法的图形方向,这是一个固有的难题。所以,输出有时是乱码。CAM::PDF 捆绑了一个getpdftext.pl程序,或者您可以像这样调用该功能:

my $doc = CAM::PDF->new($filename) || die "$CAM::PDF::errstr\n";
for my $pagenum (1 .. $doc->numPages()) {
   my $text = $doc->getPageText($pagenum);
   print $text;
}
于 2008-09-30T05:52:26.463 回答
2

我第二个亚当贝莱尔解决方案。我使用 pdftotext 实用程序来创建我的电子书库的全文索引。它有点慢,但可以完成它的工作。至于全文,可以试试 PLucene 或者 KinoSearch 来存储全文索引。

于 2008-09-26T12:31:56.303 回答
2

您可能想查看PDF::Core

于 2008-09-26T12:50:25.883 回答
1

我用过的最简单的全文索引/搜索是 mysql。您只需插入带有适当索引的表即可。您需要花一些时间来计算字段的相对权重(标题中的匹配可能比正文中的匹配得分更高),但这一切都是可能的,尽管有一些毛茸茸的 sql。

Plucene 已被弃用(过去两年没有任何积极的工作)支持 KinoSearch。KinoSearch 的成长,部分是因为理解 Plucene 的架构限制。

如果您有大约 300 个 pdf,那么一旦您从 PDF 中提取了文本(假设 PDF 有文本而不仅仅是文本图像;)并且根据您的查询量,您可能会发现 grep 就足够了。

但是,我强烈建议使用 mysql/kinosearch 路线,因为它们涵盖了很多领域(词干、停用词、术语权重、令牌解析),您不会从陷入困境中受益。

KinoSearch 可能比 mysql 路由更快,但是 mysql 路由为您提供了更广泛使用的标准软件/工具/开发人员体验。您还可以使用 sql 的强大功能来增强您的自由文本搜索查询。

所以除非你在谈论巨大的数据集和疯狂的查询量,否则我的钱会花在 mysql 上。

于 2008-09-26T13:14:01.850 回答
0

您可以尝试 Lucene(Perl 端口称为 Plucene)。搜索速度非常快,而且我知道 PDFBox 已经知道如何使用 Lucene 索引 PDF 文件。PDFBox 是 Java,但很可能在 CPAN 中的某个地方有一些非常相似的东西。即使您找不到已经将 PDF 文件添加到 Lucene 索引的内容,您自己也应该只需要几行代码即可。Lucene 将为您提供更多的搜索选项,而不是简单地在文件中查找字符串。

还有一种非常快速和肮脏的方式。PDF 文件中的文本实际上存储为纯文本。如果您在文本编辑器中打开 PDF 或使用“字符串”,您可以在其中看到文本。二进制垃圾通常是嵌入的字体、图像等。

于 2008-10-02T15:24:46.353 回答