3

入力ファイルの各行を読み取り(IN)、行が「ab」、「cd」、「ef」、「gh」などのパターンのいずれかで始まる場合、読み取った行を出力ファイル(OUT)に出力しています。 、"ij" など。出力される行は、"pattern: 100" または "pattern: 100:200" の形式です。「pattern」を「myPattern」に置き換える必要があります。つまり、現在の行を FILE に出力しますが、「:」が最初に出現する前のすべてのテキストを「myPattern」に置き換えます。これを行う最善の方法は何ですか?

現在私は持っています:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

「パターン」は「ab」または「cd」または「ef」または「gh」などのいずれかになる可能性があるため、substrの置換が役立つかどうかはわかりません。

ありがとう!バイ

4

6 に答える 6

3

一般的には、次のようにします。

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

ソートは最も長いものを最初に配置するため、データに ab:: があり、ab と ab: の両方が置換されている場合、ab の代わりに ab: が使用されます。

于 2009-06-15T23:29:34.860 に答える
1

デフォルトでは、Perl の置換演算子は (a) 最初の一致を使用し、(b) 1 つの一致のみを置換し、(c) 置換が行われた場合は true を返し、そうでない場合は false を返します。

そう:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

あなたのために働くはずです。短絡のため、1 つの置換のみが行われることに注意してください。

于 2009-06-15T20:35:26.060 に答える
0
while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}
于 2009-06-15T20:35:02.957 に答える
0

これはあなたが望むものかもしれません:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}
于 2009-06-15T20:35:31.487 に答える
0
sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

私の perl は少し錆びているので、構文が正確でない可能性があります。

edit : ya の関数に入れます。

于 2009-06-15T20:37:49.500 に答える
0

上記のことを行う最短の方法は、コードを再利用することですが、置換を含めます。

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

左側のパターンのいずれかが置き換えられます。左辺が一致しない場合、何も印刷されません。

于 2009-06-15T20:53:45.890 に答える