繁体   English   中英

Perl在循环中的两个字符串匹配的第一个实例

[英]Perl first instances of two string matches inside a while loop

我希望问一下在while循环中找到几个不同字符串的第一个实例的最简单方法是什么。 我正在动态搜索日志中的两个字符串,字符串的顺序不是必需的,任何时候都可以发生。 但是,偶尔在日志的下方(第一个实例之后)还有相同字符串的其他实例,因此我希望仅收集两个字符串的第一个实例,并收集必要的时间戳。 到目前为止,我的代码是...

while(<$log_DUT>) {
    $fh_DUT->print($_);
    if (m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB0\]/){
        $dsub1found = 1;
        open (DUTfFILE, ">>", "$TimeDutfsub1");
        print DUTfFILE DUTcurTime(),"\n";
        close (DUTfFILE);
    }

    if (m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB1\]/){
        $dsub2found = 1;
        open (DUTfFILE, ">>", "$TimeDutfsub2");
        print DUTfFILE DUTcurTime(),"\n";
        close (DUTfFILE);
    }
    last if ($dsub1found & $dsub2found == 1);
}

该脚本可以正常运行,并且在与正确的字符串(regex)触发器匹配时成功捕获了时间戳,但是如果循环仍需要等待第二个regex字符串,则它将继续捕获同一字符串的其他实例(反之亦然)。

我可以用if例如,如果$ dsub1found!= 1来开始if语句,但是没有运气,永远找不到字符串并且我的脚本超时。

我还担心的另一个问题是,在同一while循环中进行几个字符串搜索是否明智。

感谢您阅读本文,MikG

while (<$log_DUT>) {
    $fh_DUT->print($_);
    if (!$dsub1found && m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB0\]/){
       ...
    }

    if (!$dsub2found && m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB1\]/){
       ...
    }

    last if $dsub1found && $dsub2found;
}

但是为什么所有的重复呢?

my @TimeDutfsub = ( $TimeDutfsub1, $TimeDutfsub2 );

my @dsubfound;
while (keys(%seen) != 2 && ($_ = <$log_DUT>)) {
    $fh_DUT->print($_);
    if (my ($n) = m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB([01])\]/){
        if (!$dsubfound[$n]++) {
           open(my $DUTfFILE, ">>", $TimeDutfsub[$n]) or die $!;
           print $DUTfFILE DUTcurTime(),"\n";
        }
    }
}

好吧,首先,您似乎需要在while循环的一个交互中匹配这两个字符串(基于事实,有两个单独的if语句)。 对于这种情况,应在每次迭代开始时将$ dsub1found和$ dsub2found初始化为零。

其次,“&”是按位加法运算,可能不是您想要的。 我假设您的意思是“ &&”。

if ($dsub1found && $dsub2found == 1)

这将检查$ dsub1found为true且$ dsub2found等于1。如果这两个变量的初始值为0,则

if ($dsub1found && $dsub2found)

足够了。 但是,如果您希望它们都等于1,则需要:

if ( $dsub1found == 1 and $dsub2found == 1 )

如果仍然不起作用,请尝试在while循环结束时打印$ dsubfound变量值以进行调试。 也许也打印输出,然后看看发生了什么。

首先,除非您有计划,否则我会说您很幸运

您的if语句应该起作用,因为

(1&1)= 1仅针对1

甚至==的优先级&也适用于您

($ a&$ b == 1)=>($ a&($ b == 1))

情况1 a = 0,b = 0 =>(0&(0 == 1))=>(0&0)=>(0)

情况2 a = 0,b = 1 =>(0&(1 == 1))=>(0&1)=>(0)错误

情况3 a = 1,b = 0 =>(1&(0 == 1))=>(1&0)=>(0)错误

情况4 a = 1,b = 1 =>(1&(1 == 1))=>(1&1)=>(1)是

您的测试似乎对我有用,我的文件输入是新行中的“ a sd ba 1 ba 2 b”,它仅在第一个实例中显示ab

while ( <$FH> )
{
  if ( $_ =~ /a/ )
  {
    $flag_a=1;
    print $_ ;
  }
  if ( $_ =~ /b/ )
  {
    $flag_b=1;
    print $_ ;
  }

  last  if( $flag_a & $flag_b ==1 );

}

检查您是否正在使用dsub1found和dsub2found值,因为您的if条件非常依赖于此。 我建议您使用以上建议,使您的身份证状况更健全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM