我有一个程序可以将运行的周期数打印到日志文件中。我想检索日志文件中的最后一个值来找出运行周期的总数。我使用下面的代码:每个正则表达式的最后一场比赛
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;
是否有存储的最后一个匹配的值,这样我可以使用,而不是在一个阵列收集周期的perl的特殊变量?
我有一个程序可以将运行的周期数打印到日志文件中。我想检索日志文件中的最后一个值来找出运行周期的总数。我使用下面的代码:每个正则表达式的最后一场比赛
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;
是否有存储的最后一个匹配的值,这样我可以使用,而不是在一个阵列收集周期的perl的特殊变量?
你可以使用一个负先行断言:
($run{cycles}) = $log =~ /\s+(\d+)\s+Cycles(?!.*\s+\d+\s+Cycles)/gsm;
意为“发现的由空格前面和后面的空格 和文字Cycles
数字序列,也就是后面没有空格的另一序列,数字,空白和文字Cycles
“。
我想这是你想要什么:
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $+ if @cycles;
请注意,squiguy表示,$1
应该做的伎俩太(至少它为我的作品)。
最后,如果你不真的需要所有周期保存到一个数组,但只是想最后一个值,你可以这样做:
($run{cycles}) = $log =~ /.+\s(\d+)\s+Cycles/s;
你的问题是不完整的。您没有在您的代码中显示您将日志文件写入$ log的部分内容。假设你的日志文件的名称是$日志文件你的问题是如何提高:
my $log = do { local(@ARGV, $/) = $logFile ; <> } ;
my @cycles = $log =~ /\s+(\d+)\s+Cycles/gsm;
$run{cycles} = $cycles[-1] if @cycles;
答案是在一个时间来阅读你的日志文件中的一行:
open my $logFH,'<',$logFile
or die "Could not open $logFile: $!";
my $cycles;
while (my $logLine = <$logFH>) {
($cycles) = $logLine =~ /\s+(\d+)\s+Cycles/;
}
close $logFH;
$run{cycles} = $cycles
if $cycles;
这样你的程序仅使用$ logFile中最长行的空间而不是整个文件的空间,以及用于存储单个周期而不是全部空间的空间。
也就是说,I/O数量是相同的,但内存使用量要低得多。
你原来的计划是:
这个程序是:
我不会建议将整个日志文件读入内存,但如果没有关于您在做什么的更多信息,我不能写出适当的逐行解决方案。
与/g
修饰符正则表达式停止在下一个比赛,所以你只需要一个while
循环。
注意,存在使用/m
或/s
改性剂是没有意义的,因为他们做的是修改的元字符^
,$
和.
的功能。既然你没有使用这些,他们没有任何作用。
while ($log =~ /\s+(\d+)\s+Cycles/g) {
$run{cycles} = $1;
}
为什么不只是使用File::ReadBackwards
并采取“第一”匹配线。
$bw = File::ReadBackwards->new('log_file')
or die "can't read 'log_file' $!"
;
while(defined($log_line = $bw->readline)) {
next unless m/\s+(\d+)\s+Cycles/;
print;
last;
}
它应该是一个整体快得多。
你的意思是“$ 1”吗?看看'perldoc perlvar'。你在正则表达式中捕获它,你只需要使用它。 – squiguy 2013-03-14 17:22:53
不,$ 1包含匹配的第一个字符串,而不是最后一个。在我的情况下,正则表达式会在文件中找到几个匹配,我想要最后一次匹配的值 – user2050283 2013-03-14 17:39:33