5

置換の修飾子として変数を使用する方法はありますか?

my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'ee';

s/$search/$replace/$modifier;

一括検索を行うには、ハッシュの配列を使用する必要があります。さまざまな修飾子に置き換えてください。

4

5 に答える 5

4

eval安全ゴーグルとゼロ除算のスーツを着用すれば、を使用できます。

例えば:

use strict;
use warnings;
sub mk_re {
  my ($search, $replace, $modifier) = @_;
  $modifier ||= '';
  die "Bad modifier $modifier" unless $modifier =~ /^[msixge]*$/;
  my $sub = eval "sub { s/($search)/$replace/$modifier; }";
  die "Error making regex for [$search][$replace][$modifier]: $@" unless $sub;
  return $sub;
}

my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'e';

# Sub can be stored in an array or hash
my $sub = mk_re($search, $replace, $modifier);

$_ = "abc-looking-def";
print "$_\n";
$sub->();
print "$_\n";
于 2010-07-13T14:56:37.163 に答える
4

新しい置換をコンパイルするために使用する方法evalはおそらく最も簡単ですが、よりモジュール化された置換を作成できます。

use warnings;
use strict;

sub subst {
    my ($search, $replace, $mod) = @_;

    if (my $eval = $mod =~ s/e//g) {
        $replace = qq{'$replace'};
        $replace = "eval($replace)" for 1 .. $eval;
    } else {
        $replace = qq{"$replace"};
    }
    sub {s/(?$mod)$search/$replace/ee}
}

my $sub = subst '(abc)', 'uc $1', 'ise';

local $_ = "my Abc string";

$sub->();

print "$_\n";  # prints "my ABC string"

これは簡単にテストされているだけであり、読者が次のような他のフラグを実装するための演習として残されていますg

于 2010-07-13T18:52:29.297 に答える
3

うーん、もし私がそれをしなければならなかったら、私はこれをしたいと思います:

use warnings;
use strict;
my @stuff = (
{
    search => "this",
    replace => "that",
    modifier => "g",
},
{
    search => "ono",
    replace => "wendy",
    modifier => "i",
}
);
$_ = "this ono boo this\n";
for my $h (@stuff) {
    if ($h->{modifier} eq 'g') {
        s/$h->{search}/$h->{replace}/g;
    } elsif ($h->{modifier} eq 'i') {
        s/$h->{search}/$h->{replace}/i;
    }
    # etc.
}
print;

使用したい修飾子は非常に多いので、これは簡単だと思います。

これに使用できますevalが、ひどく面倒です。

于 2010-07-13T15:42:52.840 に答える
2

もちろんs/$search/$replace/、期待どおりに機能します。単純ではないのは動的修飾子です。

通常の一致修飾子pimsx場合、Perlの拡張パターンを使用して、パターンの一部としてその場で修飾子フラグを変更できます。これらは、これらの(?pimsx-imsx)修飾子をオン/オフにする形式です。

s// eおよびフォームについては、同じperlreセクションに記載されているドキュメントをee使用できます。またはフォーム(?{ perl code})のすべてについて、結果のコードのセキュリティを考慮してください。eval eee

私が知っている最初の一致にグローバルを変更するフォームはないので、グローバルと最初の一致は別々のステートメントである必要があります。

于 2010-07-13T19:02:18.090 に答える
2

これがキノピコの答えと評価の組み合わせです。

evalここでは、制御された保守可能な方法でルックアップテーブルを生成するために使用され、ルックアップテーブルは、見るのが面白くないすべてのif .. elsif..elsifを保存するために使用されます。

(非常に軽くテスト済み)

my @stuff = (
{
    search => "this",
    replace => "that",
    modifier => "g",
},
{
    search => "ono",
    replace => "wendy",
    modifier => "i",
}
);
$_ = "this ono boo this\n";

my @modifiers = qw{m s i x g e};

my $s_lookup = {};

foreach my $modifier (@modifiers) { 
    $s_lookup->{$modifier} =  eval " sub { s/\$_[0]/\$_[1]/$modifier } ";
}

for my $h (@stuff) {
    $s_lookup->{$h->{modifier}}->($h->{search},$h->{replace});
}

print; 

これが完全に役立つためには、次のものが必要です。

  1. 可能な修飾子の組み合わせ
  2. ルックアップテーブルで関数を並べ替えて、「msi」の組み合わせと「mis」の組み合わせが同じキーに移動するようにします。
于 2010-07-13T21:56:40.487 に答える