我有一堆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`;
有帮助吗?

解决方案

PerlMonks主题此处讨论此问题。

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

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

其他提示

我的第二个Adam Bellaire解决方案。我使用pdftotext实用程序来创建我的电子书库的全文索引。它有点慢,但它的工作。至于全文,请尝试PLucene或KinoSearch来存储全文索引。

我的图书馆, 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;
}

您可能需要查看 PDF :: Core

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

Plucene已被弃用(过去两年没有任何积极的工作)支持KinoSearch。 KinoSearch在一定程度上增长了对Plucene的架构限制的理解。

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

然而,我强烈建议使用mysql / kinosearch路由,因为它们已经涵盖了很多基础(词干,停用词,术语加权,令牌解析),而这些路线并没有因为陷入困境而受益。

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

因此,除非您正在讨论巨大的数据集和疯狂的查询量,否则我的资金将用于mysql。

您可以尝试使用Lucene(Perl端口称为Plucene)。搜索速度非常快,我知道PDFBox已经知道如何使用Lucene索引PDF文件。 PDFBox是Java,但在CPAN的某处可能存在非常类似的东西。即使你找不到已经将PDF文件添加到Lucene索引中的东西,也不应该自己做几行代码。 Lucene将为您提供更多搜索选项,而不仅仅是在文件中查找字符串。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top