2014-01-10 109 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使用以上建議,並使您的身份證條件健全。