检查datafile中的行是否包含数组元素

时间:2015-07-13 21:19:34

标签: arrays perl

我有一个包含关键字列表的文件。我有第二个包含几千行数据的数据文件。我已经将包含关键字的文件读入数组,我现在想要获取数组中的第一个元素,遍历文件中的行并打印包含该数组元素的任何值。然后移动到数组中的下一个元素并重复该过程。

到目前为止,我的代码如下,但它似乎没有做任何事情。我不知道我想做的事情是否可能。任何帮助,将不胜感激。

use strict;
use warnings; 

my $keywords= shift;
my $data= shift;

#reading in keywords file and storing in array
open (FH, "< $keywords");
my @keywords= <FH>;
close FH;

# now I want to iterate over the array and for each element loop through
# the datafile checking if the element exists in the line

open (DATAFILE, "< $data");
for my $element (@keywords) {
    for my $line (<DATAFILE>) {
        if ($line =~ /\Q$element\E/) {
            print $line;
        }
    }
}
close DATAFILE;

2 个答案:

答案 0 :(得分:1)

首先,您应该始终检查您的文件是否打开成功,并且如果没有,则会适当地抱怨。

open (FH, "< $keywords") or die "Failed to open $keywords: $!";
# ...
open (DATAFILE, "< $data") or die "Failed to open $data: $!";

其次,您的@keywords数组由末尾带换行符的字符串组成,就像它们出现在文件中一样。你可能不希望这样。这样做是为了在阅读文件时删除换行符:

chomp(my @keywords = <FH>);

第三,在您第一次通过$element循环读完数据文件之后,您已经在文件的末尾,并且在连续的$element循环中再次读取它将只是马上回来。最快的解决方法是将seek DATAFILE, 0, 0;添加到$element循环的底部。这会将文件指针移回文件的开头,以便您可以再次读取它。

最后,如果您提供了两个文件内容的示例以及您希望脚本生成的输出,那将会很有帮助。

另一个调试提示:如果我不明白为什么我没有得到我预期的所有匹配,我会添加这样的打印语句:

for my $element (@keywords) {
    print "Starting to search for <$element>\n";
    for my $line (<DATAFILE>) {
        print "Examining line <$line>\n";
        # ...
    }
}

这会在$element中显示换行符,并且在第一次通过该文件后您也不会看到Examining line <$line>

答案 1 :(得分:-1)

这个程序对输入文件做了一些假设(例如,关键字文件只包含一个单词,而不是包含空格的短语)但它可能是实现目标的最快捷,最方便的方法

关键字文件中的键是唯一的,并按长度的递减顺序排序(因此当字符串为off时找不到offer)并且所有非字符都是使用quotemeta进行转义,以便逐字匹配,而不是作为转义序列的一部分

然后构建一个正则表达式模式,以便优化关键字搜索(从版本5.10开始,Perl正则表达式引擎为替代列表构建trie

仍有问题,例如,如果que是关键字,但antique不是,则搜索将返回误报。可以通过明智地使用字边界正则表达式模式\b来改进它,但这带来了新的问题,例如sign是关键字但是{{1}不是,然后再次搜索将返回误报。诸如此类的问题对单个数据集非常敏感,并且解决方案不能以与列出的假设相同的方式进行推广

re-sign