2016-04-26 37 views
2

我有這個數組。爲什麼perl正則表達式不起作用?

my @input = ("He walk+V3SG very fast.", "He study+V3SG hard."); 

我想用'walk + V3SG'和'study + V3SG'來代替'走路'和'學習'。

下面是我寫的腳本。我認爲這應該工作,但由於某種原因,它不工作。

foreach my $sent(@input){ 
    if ($sent =~ m/\Q+V3SG/){ 
     if ($sent =~ m/\Q[dlr]y+V3SG/){ 
      $sent =~ s/\Q[dlr]y+V3SG/ies/g; 
     } 
     if ($sent =~ m/\Q[s|x|sh|ch|o]+V3SG/){ 
      $sent =~ s/\Q[s|x|sh|ch|o]+V3SG/es/g; 
     } 
     else {$sent =~ s/\Q+V3SG/s/g} 
    } 
} 

foreach my $sent(@input){ 
    print $sent; 
    print "\n"; 
} 

誰能告訴我這個腳本有什麼問題嗎?

回答

2

\Q使正則表達式的其餘部分符合字面意思[dlr]y+V3SG。移動它使字符類正常工作:

s/[dlr]\Qy+V3SG/ies/g 

或只是逃避+

s/[dlr]y\+V3SG/ies/g 

此更改後,你得到的,例如:

He stuies hard. 

要確保第一個字母被保留,您可以使用捕獲或\K(自5.10):

s/[dlr]\K\Qy+V3SG/ies/g 

對於第二個正則表達式,你使用了錯誤的括號:

s/(s|x|sh|ch|o)\Q+V3SG/$1es/g 
+1

此外,他們不應該使用if/ELSIF /別的都沒有。這句話可以包含所有三種形式。 – ikegami

+0

非常感謝你(; –

0

你應該保持\Q之前只是文字。你把它放在整個正則表達式之前,所以整個正則表達式被認爲是字面的,並沒有被解釋。

第二件事你應該明智地用\K來代替。把它放在你不想替換的部分之後。例如:s/[dlr]\Ky\Q+V3SG/ies/g使得studystudies並且它不會從結果中刪除dlr

第三件事[s|x|sh|ch|o]不會做你的想法。它將匹配s,x,h,|,c,o中的任何字符。正確的應該是(?:s|x|sh|ch|o)(?:...)用於非捕獲組。

最後,這應該不是一個if/elsif/else。這句話可以包含所有三種形式。

總評:它給我們:

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

my @input = ("He walk+V3SG very fast.", "He study+V3SG hard.","He crush+V3SG hard."); 

foreach (@input){ 
    if (m/\Q+V3SG/){ 
     s/[dlr]\Ky\Q+V3SG/ies/g; 
     s/(?:s|x|sh|ch|o)\K\Q+V3SG/es/g; 
     s/\Q+V3SG/s/g; 
    } 
} 

foreach my $sent(@input){ 
    print $sent; 
    print "\n"; 
} 
+0

非常感謝你! –

相關問題