簡體   English   中英

如何在替換中使用變量作為修飾符

[英]How to use a variable as modifier in a substitution

有沒有辦法在替換中使用變量作為修飾符?

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

s/$search/$replace/$modifier;

我需要使用散列數組來使用不同的修飾符進行批量搜索替換。

如果您戴上護目鏡和除零套裝,則可以使用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";

雖然使用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

嗯,如果我必須這樣做,我會這樣做:

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 ,但它非常混亂。

當然s/$search/$replace/可以按您的預期工作。 動態修飾符並不簡單。

對於pimsx的常規匹配修飾符,您可以使用 Perl 的擴展模式來動態修改修飾符標志作為模式的一部分。 這些是(?pimsx-imsx)來打開/關閉這些修飾符。

對於s// eee形式,您可以使用(?{ perl code})記錄在同一 perlre 部分中。 對於所有eval eee形式,請考慮結果代碼的安全性!

我知道沒有將 global 修改為第一個匹配的形式,因此 global vs first match 需要是單獨的語句。

這是 Kinopiko 的答案和 eval 的組合。

這里使用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”組合將轉到相同的鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM