0

これは私を夢中にさせています。ヘルプ?

Perl ループ内のように見えますforeachが、置換パターンの外側の変数は期待どおりに変更されますが、置換パターンの内側の変数は「スタック」します。あたかも perl がコード ブロックs///内で置換パターンに遭遇した場合foreach、最初はループを介して置換パターンの内容を補間し、2 回目は補間しないようです。

ここにいくつかのテストコードがあります:

#!/usr/bin/perl

@replacements=("a", "b", "c");
@input=("xxletterxx");

foreach $replacement (@replacements) {
        foreach $line (@input) {
                $line=~s/xxletterxx/$replacement/g;
                print "R: $replacement\n";
                print "L: $line\n";
        }
}

これを印刷する必要があると思います:

R: a   
L: a   
R: b   
L: b   
R: c   
L: c

...しかし、代わりにこれを出力します:

R: a  
L: a  
R: b  
L: a  <--- Why isn't this 'b'?  
R: c  
L: a  <--- Why isn't this 'c'?  

コード ブロックの他の場所で@replacements?

何故ですか?

Perl が突然壊れたような気がします。

この DOS の動作は perl で発生しているようです。

4

3 に答える 3

6

このループ制御:

foreach $line (@input)

$lineの各要素のエイリアスな@inputので、最初に置換を行うと、変更されるだけで$lineなく、変更も行わ$input[0]れます。その後、xxletterxxがなくなったので、/xxletterxx/が一致しないため、これ以上の置換は行われません。

@input希望どおりに動作させるには、配列のクローンを反復処理することにより、エイリアシングを解除する必要があります。

foreach $line (@{[@input]})

$lineまたは、変更する前に別の変数にコピーし$lineて、ループの本体で読み取り専用として扱います。

foreach $line (@input) {
        $modifiedline = $line;
        $modifiedline=~s/xxletterxx/$replacement/g;
        print "R: $replacement\n";
        print "L: $modifiedline\n";
}
于 2012-08-31T00:27:52.960 に答える
0

Hobbs が言ったように、問題は で置換xxletterxxするとa、パターンが一致しなくなり、置換が行われないことです。あなたの最終的な目標が何であるかはわかりませんが、これはうまくいきます

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");

foreach my $replacement (@replacements) {
  my $line = "xxletterxx";
  $line=~s/xxletterxx/$replacement/g;
  print "R: $replacement\n";
  print "L: $line\n";
}

これもそうです

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");
my @lines = ("xxletterxx") x 3;

foreach my $replacement (@replacements) {
  my $line = shift @lines;
  $line=~s/xxletterxx/$replacement/g;
  print "R: $replacement\n";
  print "L: $line\n";
}

さらに、私はあなたのために追加strictwarningsました:-)

編集:おそらくより興味深い例は、最後の変更であり、置換ごとに各要素を@lines順番に変更しようとし、置換が成功すると停止します。

#!/usr/bin/env perl

use warnings;
use strict;

my @replacements=("a", "b", "c");
my @lines = ("xxletterxx") x 3;

foreach my $replacement (@replacements) {
  foreach my $line (@lines) {
    last if $line=~s/xxletterxx/$replacement/g;
  }

  print "R: $replacement\n";
  print "A: @lines\n";
}
于 2012-08-31T00:40:03.640 に答える
0

orxxletterxxで置き換える必要はありません。既に で置き換えているためです。bca

于 2012-08-31T00:28:37.543 に答える