7

私はこれを探して頭痛がしました:割り当てではなく、式でs///をどのように使用しますか。私が何を意味するのかを明確にするために、次のコンテキストで使用される場合、Pythonのre.sub(...)に相当するperlを探しています。

newstring = re.sub('ab', 'cd', oldstring)

これまでのところ、perlでこれを行う方法を私が知っている唯一の方法は次のとおりです。

$oldstring =~ s/ab/cd/;
$newstring = $oldstring;

追加の割り当てに注意してください。

4

5 に答える 5

11

($new = $old) =~ s/whatever/whateverelse/;探しているものとまったく同じ機能に使用できます。

use strict;
my $old = "OLD";
my $new;
($new = $old) =~ s/OLD/NEW/;
print "old=$old, new=$new";

生産:

old=OLD, new=NEW

まさにあなたが望むもの

関数を探している場合は、割り当てを回避するために独自の関数を定義できます。

use strict;
sub re_sub { 
   my ($find, $replace, $old) = @_;
   my $new = $old;
   $new =~ s/$find/$replace/;
   return $new;
}

my $old = "ab";
my $new = re_sub('ab', 'cd', $old);
print "new=$new\n";

結果はnew=cd

于 2010-04-19T01:57:47.560 に答える
7

Perlの正規表現置換は、常に「インプレース」で行われます。したがって、文字列を新しい変数にコピーして、新しい変数を操作する必要があります。

(my $newstring = $oldstring) =~ s/ab/cd/;
于 2010-04-19T02:00:32.343 に答える
7

あなたはどのように機能するかについて誤解しているようです=~=~変数を正規表現演算子に関連付けるバインディング演算子です。割り当ては行いません。

正規表現演算子はすべてデフォルトでトピック変数$_で機能するためs/foo/bar/;、と同じ$_ =~ s/foo/bar/;です。割り当ては発生しません。トピック変数が変換されます。

他の変数を操作する場合も同様です。の最初のインスタンスを。に置き換えることで$var =~ s/foo/bar/;変換します。割り当ては発生しません。$varfoobar

私があなたに与えることができる最善のアドバイスは、PythonでPythonを、PerlでPerlを書くことです。2つの言語が同じであると期待しないでください。

DVKが提案するように、慣れている置換動作を再現するサブルーチンを作成することができます。

または、慣用的なPerlを試すこともできます。1行に複数の変換を適用したいというあなたの表明された要望に基づいて、役立つと思われるいくつかの例を示しました。

ここでは、for1つのアイテムのループを使用して、$varハードコードされた多くの変換をトピック化して適用します。

for( $var ) {
    s/foo/bar/;
    s/fizz/buzz/;
    s/whop/bop-a-loo-bop/;
    s/parkay/butter/;
    s/cow/burger/;
}

または、変換の可変グループを適用する必要があるかもしれません。古い/新しい変換ペアを定義する配列参照のリストをループするサブルーチンを定義します。この例では、Perlのリスト指向の引数処理を利用して、任意の数の変換を処理します。

my $foo = transform(
    'abcd' =>
    [ 'a',  'b'    ], 
    [ 'bb', 'c'    ],
    [ 'cc', 'd'    ],
    [ 'dd', 'DONE' ],
);

sub transform {
    my $var = shift;
    for (@_ ) {
        my ($old, $new) = @$_;
        $var =~ s/$old/$new/;
    }

    return $var;
}

最後に、最初の引数を変更するバージョンの変換を提供するために少し混乱します。

my $foo = 'abcd';

transform_in_place(
    $foo =>
    [ 'a',  'b'    ], 
    [ 'bb', 'c'    ],
    [ 'cc', 'd'    ],
    [ 'dd', 'DONE' ],
);

print "$foo\n";

sub transform_in_place {
    for my $i (1..$#_ ) {
        my ($old, $new) = @{$_[$i]};
        $_[0] =~ s/$old/$new/;
    }
}

私自身のプロジェクトでは、特定の問題のニーズに応じて、おそらく最初の2つのオプションのいずれかを使用します。

于 2010-04-19T07:59:07.573 に答える
2

$ newstringを置換の結果にしたいですよね?

このようなもの:

($newstring = $oldstring) =~ s/ab/cd;

動作するはずです。割り当てはに設定$newstringされ$oldstring、次にに評価さ$newstringれます。これは、置換が作用するものです。

于 2010-04-19T02:02:08.653 に答える
1

これに基づいて、1つの行に2つのs ///を含めることはできず、一方は他方の結果を使用し、中間の割り当てはないと仮定するのは正しいですか?– mikeY

はい。それで合っています。同じ文字列に複数の置換を適用したい場合は、

    $newstring = $oldstring ;
    $newstring  =~ s/ab/cd/ ;
    $newstring  =~ s/xx/yy/ ;

以下はs//、変更された文字列ではなく、行われた置換の数を返すため、機能しません。

    $newstring = $oldstring) =~ s/ab/cd/ =~ s/xx/yy/ ;

要約すると、Perlの正規表現操作はPythonの操作とは大きく異なり、Pythonの概念をPerlにマッピングするよりも、Perlが何をするのかを最初から学ぶ方がよいでしょう。

于 2010-04-19T08:08:36.207 に答える