Regex 如何找到以“结束”结尾的最后一行;通行证;在我的文本文件中?

Regex 如何找到以“结束”结尾的最后一行;通行证;在我的文本文件中?,regex,perl,Regex,Perl,我有一个如下所示的文本文件: --------- Voltage = 1.150000 V --------->PASS --------- Voltage = 1.140000 V --------->PASS --------- Voltage = 1.130000 V --------->PASS --------- Voltage = 1.120000 V --------->PASS --------- Voltage = 1.1

我有一个如下所示的文本文件:

--------- 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?
        }
    }
}
打开(我的$FH,$FileName)或死亡“$!\n”;
而($line=)
{
如果($line=~/FAIL/)
{
如果($line=~m/^\d*\.?\d*/)#检查十进制数?不确定
{
打印$&;#我想在这里打印匹配的号码吗?
}
}
}

由于
^
的原因,您正在字符串开头查找一个数字。当然,那里没有。您可以使用
/(\d+(?:\。\d+)/
提取数字,但为什么不只提取下面的
电压=

你说你想要最后一个通过的电压,但你试图捕捉失败的电压

避免使用
$&
,因为它会减慢每次匹配和替换的速度,而不会捕获

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");

这将读取整个文件,然后打印匹配的最后一行的数字

while (<>)
{
    # last if m/FAIL$/;  # see below
    next unless m/(\d+\.\d) V/;  # Capture number in $1
    $keep = $1 if m/PASS$/;
}
print $keep;

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";
}
打开(我的$FH,$FileName)或死亡“$!\n”;
#建议对海报进行更改
#打开(FH,$fileName)}或死“发现未打开文件$1\n”;
$lastPass=“init”#如果第一行出现故障。
而($line=){
接下来如果$line=~/^$/;#如果没有字符串数据,为什么还要麻烦呢
如果($line=~/FAIL/i){#查找失败
打印“检测到失败的$line\n”#打印警告
最后;#退出循环
}
否则{
如果($line=~m/(\d*\?\d*)/){如果该行不是失败记录
$lastPass=$line;
$voltage=$1;#如果希望将其存储在$1正则表达式内存中,则为voltage
}       
}
}
#关闭(FH);#建议
如果($lastPass eq“init”){#我们在通过之前发现了失败。
打印“在良好数据之前检测到失败\n”;
}
否则{
打印$lastPass,“\n”;
打印$voltage,“\n”;
}

我使用的分隔符是“\n\n\n\n”。定义为$/=“\n\n\n\n”;谢谢大家的帮助。我会继续跟进这个问题。向您介绍我的最终解决方案或其他问题。Perl有这样一个活跃的社区。感谢您的帮助。这捕获了失败的值,但最后一次成功通过的值在哪里?是的,您是对的。关于最后一次良好通过值。当所有过程都通过时,则最后一个过程应为预期值。当它在任何点失败时,最后一个良好通过值就是预期值。这个问题仍然没有解决。输入是一个文件,而不是键盘。@alexmac调用脚本时,需要将文件名作为命令行参数传递。+1就我个人而言,我喜欢你的一行代码!虽然它(以及你更完整的答案)将失败,如果有人把他们的探头从后到前,电压是负的:-)他们说把它作为命令行传递进来了吗?我想这是一大套代码的一部分。不过,我并没有足够的诚意去否决它。@alexmac如果您对Unix工具设计不感兴趣,可以在脚本的开头添加一个
打开的
。更好的是,学会欣赏灵活性。太好了,这很优雅。一个小问题是,如果您定义了$pass,但从未修改其间的值,那么if($pass eq“init”)将始终被打印出来。它是功能性的,当然,但并不优雅。有一些缺点可以去掉,使它不必使用
use strict编译。。。。并将错误写入标准输出,在换行前输出空格,etc@user3368737不要注释掉
使用strict只是为了让你在互联网上找到的代码正常工作。你应该经常使用它。如果
strict
不起作用,则代码有问题,而不是
strict
有问题。
perl -ne 'next unless m/(\d+\.\d+) V .*PASS$/; $k = $1; END { print $k }' filename
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";
}