2015-08-31 85 views
0

我想從我的文件中存在的字符串中刪除單詞Z或ZN和LVT,但我無法得到它。有人可以檢查我的代碼。使用Perl從字符串中刪除匹配的單詞

輸入

abchsfk/jshflka/ZN      (cellLVT) 
asjkfsa/sfklfkshfsf/Z     (mobLVT) 
asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z  (celLVT) 
asjhdjs/jhskjds/ZN      (abcLVT) 
shdsjk/jhskd/ZN       (xyzLVT) 

輸出

abchsfk/jshflka      cell 
asjkfsa/sfklfkshfsf     mob 
asjhfdjkfd/sjfdskjfhdk/hsakfshf  cel 
asjhdjs/jhskjds      abc 
shdsjk/jhskd      xyz 

CODE:

 if ($line =~ /LVT/ && ($line =~ /ZN/ || $line =~ /Z/))   

     #### matches the words LVT and (Z or ZN) 

     { 
      my @names = split//, $line;  ##### splits the line 


       $names[2] =~ s/\/Z|/ZN//g;  #### remove Z or ZN 
       $names[3] =~ s/\(|LVT\)//g ; #### remove LVT & braces 

       print OUT " $names[2] $names[3] \n"; #### print 

     } 
+1

爲什麼不'$線=〜S/\/ZN | LVT //克;' – sln

+0

@sln?謝謝。我想要一起移除「/ Z」和「/ ZN」,而不是僅移除Z或ZN。我也想去掉大括號。所以我試圖先將它拆分,然後嘗試逐個刪除它。 – SKG

+0

@sln。我從你提出的想法中嘗試了這種方式。它爲我工作。 '$ line =〜s/\/ZN?| \(| LVT \)// g;' – SKG

回答

2

的問題是匹配的順序爲:(!第二反斜槓丟失在代碼中)s/\/Z|\/ZN//g。您應該首先匹配較長的字符串,否則Z將匹配並且N不會被刪除。

甚至還有更簡單的方法,但:只需使用\/ZN?

#!/usr/bin/perl 
use warnings; 
use strict; 

while (my $line = <DATA>) { 
    if ($line =~ /LVT/ && $line =~ /ZN?/) { 

     my @names = split ' ', $line; 
     $names[0] =~ s/\/ZN?//g; 
     $names[1] =~ s/\(|LVT\)//g; 
     print "$names[0] $names[1]\n"; 
    } 
} 
__DATA__ 
abchsfk/jshflka/ZN      (cellLVT) 
asjkfsa/sfklfkshfsf/Z     (mobLVT) 
asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z  (celLVT) 
asjhdjs/jhskjds/ZN      (abcLVT) 
shdsjk/jhskd/ZN       (xyzLVT) 
+0

感謝您的解釋。它真的有幫助 – SKG

+0

我還有一個問題要問這個。在我的輸出中。一些線路被重複。我想對它們進行分類並僅打印一次。我可以使用排序功能嗎?這裏是我想要的 'while(my $ line = ){if($ line =〜/ zN?/){' my @names = split'', $線; $ names [0] =〜s/\/ZN?// g; $ names [1] =〜s/\(| LVT \)// g; my @line_out =「$ names [0] $ names [1]」; $ lvt_out = sort :: $ line_out(); print「$ lvt_out \ n」; }' – SKG

+2

@SKG:你應該在一個新的問題中提出一個新的問題。 – choroba