2014-01-10 108 views
0

内的两个字符串匹配的第一个例子,我希望要问什么最简单的方法找到一个while循环中几个不同的字符串的第一个实例。我正在寻找两个字符串的日志,字符串的顺序不是必需的,可以随时发生。不过,偶尔也有相同的字符串进一步下跌的日志(一审)之后的又一实例,所以我希望能只收集两个字符串的第一个实例,并收集必要的时间戳。该代码我有多远......Perl中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); 
} 

脚本工程确定,并成功捕获时间戳,当它正确的字符串(正则表达式)触发相匹配,但它继续捕捉相同的字符串的进一步实例应的循环仍然需要等待第二个正则表达式字符串(反之亦然)。

我开始if语句(例如),如果$ dsub1found!= 1,但没有运气,字符串永远找不到,我的脚本超时。

其他担心,我不得不为它是否是明智的做一对夫妇的字符串搜索在同一个while循环。

感谢您阅读此, MikG

回答

3
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"; 
     } 
    } 
} 
+0

谢谢池上,这看起来是我以后的事情。重复仅仅是因为我是一名Perl初学者,但最终通过练习,我希望将来能够缩短我的脚本以提高效率。但事实证明,我现在对重复性格式的理解更为清晰。我尝试了你的简短脚本,但是它在'$ TimeDutfsub $ n'处摔倒了,'$ TimeDutfsub'需要定义 – MikG

+0

Re“重复纯粹是由于我是一个Perl初学者”,对不起,我的意思是修辞。我可以这样说:“但是消除所有这些重复会很容易, – ikegami

+0

Re'$ TimeDutfsub',我没有注意到前面的'$',我以为你创建了名为'TimeDutfsub1'和'TimeDutfsub2'的文件。必须使用一个数组'my @TimeDutfsub =(...,...);'并使用'$ TimeDutfsub [$ n]'(更新答案以使用数组)。 – ikegami

2

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

其次,“&”是按位与操作,就可能不是你想要的。我假定你的意思是'& &'。

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

此检查,如果$ dsub1found是真实的,$ dsub2found等于1。如果这两个变量的初始值是0,那么

if ($dsub1found && $dsub2found) 

就足够了。但是,如果你想他们都等于1,则需要:

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

如果仍然无法工作,尝试在while循环结束调试目的打印出$ dsubfound变量值。也许可以打印输入,看看发生了什么。

2

首先关闭所有我会说你是幸运的,除非你计划好了

你的if语句应该是工作,因为

(1 & 1)= 1只有你正确地对1检查

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

($ A & $ B == 1)=>($一个&($ 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)true

您测试似乎对我有用,我的文件输入是“a sd ba 1 ba 2 b”offsourse in new行,它只能打印AB一审

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

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

} 

检查,如果你的地方与你dsub1found和dsub2found值打,因为你如果条件上非常依赖。我建议yu使用以上建议,并使您的身份证条件健全。