13

変数からテキストを取得して変数に格納するのではなく、テキストを正規表現インラインに置き換える方法はありますか?

私はPerlの初心者です。私はよく自分が書いていることに気づきます

my $foo = $bar;
$foo =~ s/regex/replacement/;
doStuff($foo)

本当に書きたいところ

doStuff($bar->replace(s/regex/replacement/));

一時変数と3行を使用するのではなく、など。

これを行う方法はありますか?明らかに、正規表現が十分に複雑な場合は、より適切に説明できるように分割するのが理にかなっていますが、それだけのs/\s//g場合は、追加の変数でコードを乱雑にするのは間違っていると感じます。

4

6 に答える 6

14

1置換関数は、機能した場合はaを返し、機能しなかった場合は空の文字列を返すため、実際には必要なことを実行できません。つまり、これを行った場合:

doStuff($foo =~ s/regex/replacement/);

このdoStuff関数は1、パラメータとしてまたは空の文字列を使用します。置換関数が機能した場合だけでなく、結果の文字列を返すことができなかった理由はありません1。しかし、それはPerlの初期の頃からの設計上の決定でした。そうでなければ、これで何が起こるでしょうか?

$foo = "widget";
if ($foo =~ s/red/blue/) {
    print "We only sell blue stuff and not red stuff!\n";
}

結果の文字列はまだwidgetですが、置換は実際には失敗しました。ただし、置換によって空の文字列ではなく結果の文字列が返された場合ifでも、はtrueになります。

次に、このケースを考えてみましょう。

$bar = "FOO!";
if ($bar =~ s/FOO!//) {
   print "Fixed up \'\$bar\'!\n";
}

$bar空の文字列になりました。置換によって結果が返された場合は、空の文字列が返されます。それでも、実際に代用は成功したので、私は真実になりたいと思っていifます。

ほとんどの言語では、置換関数は結果の文字列を返すため、次のような操作を行う必要があります。

if ($bar != replace("$bar", "/FOO!//")) {
   print "Fixed up \'\$bar''!\n";
}

したがって、Perlの設計上の決定(基本的にawk構文をよりよく模倣するため)のために、あなたが望むことを行う簡単な方法はありません。ただし、これを行うこともできます。

($foo = $bar) =~ s/regex/replacement/;
doStuff($foo);

$fooこれにより、最初にの値を割り当てずに、のインプレース設定が実行されます$bar$bar変更されません。

于 2010-07-25T21:20:34.107 に答える
9

perl 5.14以降では、非破壊置換を使用して目的の動作を実現できます。

/rこれを行うには、修飾子を使用します。

doStuff($bar=~s/regex/replacement/r);
于 2016-08-10T07:36:27.843 に答える
5
use Algorithm::Loops "Filter";

# leaves $foo unchanged
doStuff( Filter { s/this/that/ } $foo );
于 2010-07-26T00:48:12.173 に答える
2

ブロックを使用do { }して、現在のスコープで一時変数が作成されないようにすることができます。

doStuff( do {(my $foo = $bar) =~ s/regex/replacement/; $foo} );
于 2010-07-25T20:43:51.600 に答える
0

これは、あなたの望むことですか?:

my $foo = 'Replace this with that';
(my $bar = $foo) =~ s/this/that/;
print "Foo: $foo\nBar: $bar\n";

プリント:

Foo: Replace this with that
Bar: Replace that with that
于 2010-07-25T20:52:48.447 に答える
-1

さらに別の方法があります。独自の関数を作成します。

sub replace (
    my $variable = shift;
    my $substring = shift;

    eval "\$variable =~ s${substring};";
    return $variable
}

doStuff(replace($foo, "/regex/replace/"));

これは1回の呼び出しでは価値がなく、その場合はコードがさらに混乱する可能性があります。ただし、これを12回ほど行う場合は、これを行うための独自の関数を作成する方が理にかなっている場合があります。

于 2010-07-25T21:35:28.440 に答える