我有一个看起来像这样的文本文件:
--------- Voltage = 1.150000 V --------->PASS
--------- Voltage = 1.140000 V --------->PASS
--------- Voltage = 1.130000 V --------->PASS
--------- Voltage = 1.120000 V --------->PASS
--------- Voltage = 1.110000 V --------->PASS
--------- Voltage = 1.100000 V --------->PASS
--------- Voltage = 1.090000 V --------->FAIL
我想检索最后一个传递值,在本例中为1.100000V
。我怎么能用正则表达式做到这一点?我尝试了以下但是没有给出正确的答案:
open(my $FH, $FileName) or die "$!\n";
while($line = <$FH>)
{
if($line =~ /FAIL/)
{
if($line =~ m/^\d*\.?\d*/) #check for the decimal number? not sure
{
print $&; # I intend to print the matched number here?
}
}
}
答案 0 :(得分:1)
由于^
,您在字符串的开头寻找一个数字。当然,那里没有一个。您可以使用/(\d+(?:\.\d+))/
提取数字,但为什么不采用Voltage =
后面的内容?
你说你想要最后通过的电压,但你试图捕获失败的电压!
避免使用$&
因为它会减慢每次匹配和替换而不会捕获。
open(my $FH, $FileName)
or die "$!\n";
my $passing_voltage;
while ($line = <$FH>) {
if (my ($voltage) = $line =~ /Voltage = (\S+)/) {
last if $line =~ /FAIL/;
$passing_voltage = $voltage;
}
}
die("No passing voltage\n") if !defined($passing_voltage);
print("$passing_voltage\n");
无需触摸$/
。
以上内容非常简单,但通过从头到尾阅读文件可以进一步简化。
use File::ReadBackwards qw( );
my $fh = File::ReadBackwards->new($FileName)
or die("$!\n");
my $voltage;
while ( defined( my $line = $fh->readline() ) ) {
if ($line =~ /Voltage = (\S+).*PASS/) {
$voltage = $1;
last;
}
}
die("No passing voltage\n") if !defined($voltage);
print("$voltage\n");
答案 1 :(得分:1)
这将读取整个文件,然后打印匹配的最后一行的数字。
while (<>)
{
# last if m/FAIL$/; # see below
next unless m/(\d+\.\d) V/; # Capture number in $1
$keep = $1 if m/PASS$/;
}
print $keep;
要进行优化,如果您知道第一个FAIL
不会被任何PASS
es跟踪,请取消注释last
行。
作为单行,
perl -ne 'next unless m/(\d+\.\d+) V .*PASS$/; $k = $1; END { print $k }' filename
答案 2 :(得分:-2)
open(my $FH, $FileName) or die "$!\n";
# suggested change for poster is
# open (FH, $fileName) } or die "found not open file $1\n";
$lastPass = "init"; # in the event of a fail on first line.
while($line = <FH>){
next if $line =~ /^$/; # if no string data why even bother
if($line =~ /FAIL/i){ # look for a fail
print "fail detected $line \n"; #print a warning
last; # exit the loop
}
else {
if ($line =~ m/(\d*\.?\d*)/) { # if the line is not a fail record
$lastPass = $line;
$voltage = $1; # voltage if you want it in the $1 regex memory
}
}
}
# close (FH); # suggestion
if ($lastPass eq "init") { # did we find a fail before a pass.
print "detected fail before good data \n";
}
else {
print $lastPass, "\n";
print $voltage , "\n";
}