2016-04-26 13 views
2

私はこの配列を持っています。なぜこのperl正規表現は機能しませんか?

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

と私は 'walk + V3SG'と 'study + V3SG'を 'walks'と 'studies'に置き換えたいと考えています。

以下は私が書いたスクリプトです。私はこれがうまくいくはずだと思ったが、なんらかの理由でそれが機能していない。

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以降)を使用することができます:

01第二の正規表現については

、間違ったブラケットを使用している:

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

をまた、彼らはすべてのELSIF/ELSE/IFを使用するべきではありません。文は3つの形式すべてを含むことができます。 – ikegami

+0

ありがとうございます( –

0

あなただけのリテラルの前に\Qを維持する必要があります。正規表現全体の前に置いているので、正規表現全体はリテラルとみなされ、解釈されません。

第2のものは、\Kを賢明に置き換えて使用してください。あなたが代用したくない部分の直後に置く。たとえば:s/[dlr]\Ky\Q+V3SG/ies/gstudystudiesとなり、結果からdまたはlまたはrは削除されません。

第3のもの[s|x|sh|ch|o]はあなたの考えをしません。 s,x,h,|,c,oの任意の文字と一致します。正しいものは(?:s|x|sh|ch|o)です。 (?:...)は非キャプチャグループ用です。

最後に、if/elsif/elseであるべきではありません。文は3つの形式すべてを含むことができます。

全体:それは私たちを与える:

#!/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

ありがとうございます! –

関連する問題