我有一个包含关键字列表的文件。我有第二个包含几千行数据的数据文件。我已经将包含关键字的文件读入数组,我现在想要获取数组中的第一个元素,遍历文件中的行并打印包含该数组元素的任何值。然后移动到数组中的下一个元素并重复该过程。
到目前为止,我的代码如下,但它似乎没有做任何事情。我不知道我想做的事情是否可能。任何帮助,将不胜感激。
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;
答案 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