如何在替换中使用变量作为修饰符

发布于 2024-09-09 05:51:51 字数 194 浏览 3 评论 0原文

有没有办法在替换中使用变量作为修饰符?

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

s/$search/$replace/$modifier;

我需要使用哈希数组来使用不同的修饰符进行批量搜索替换。

Is there a way to use a variable as modifier in a substitution?

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

s/$search/$replace/$modifier;

I need to use an array of hashes to make bulk search-replace with different modifiers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

琉璃梦幻 2024-09-16 05:51:51

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

While the method using eval to compile a new substitution is probably the most straightforward, you can create a substitution that is more modular:

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"

This is only lightly tested, and it is left as an exercise for the reader to implement other flags like g

凉墨 2024-09-16 05:51:51

如果您戴上护目镜和除零服,则可以使用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";

You could use eval, if you put on your safety goggles and your divide-by-zero suit.

E.g.:

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";
雪若未夕 2024-09-16 05:51:51

嗯,如果我必须这样做,我会这样做:

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 来实现此目的,但它非常混乱。

Hm, if I had to do it I would do like this:

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;

There are only so many different modifiers you might want to use so I think this is easy enough.

You can use eval for this, but it's awfully messy.

鹊巢 2024-09-16 05:51:51

当然 s/$search/$replace/ 按您的预期工作。动态修饰符并不简单。

对于pimsx的常规匹配修饰符,您可以使用Perl的扩展模式作为模式的一部分动态修改修饰符标志。它们的形式为 (?pimsx-imsx) 用于打开/关闭这些修饰符。

对于 s// eee 形式,您可以使用 (?{ perl code}) 中记录的相同的 perlre 部分。对于所有 eval eee 形式,请考虑结果代码的安全性!

据我所知,没有任何形式可以将全局修改为第一个匹配,因此全局与第一个匹配需要是单独的语句。

Of course s/$search/$replace/ work as you expect. It is the dynamic modifiers that are not straightforward.

For the regular match modifiers of pimsx you can use Perl's Extended Patterns to modify the modifier flags on the fly as part of your pattern. These are of the form (?pimsx-imsx) to turn on / off those modifiers.

For the s// e and ee forms, you can use (?{ perl code}) documented in the same perlre section. For all of eval e or ee forms, consider the security of the resulting code!

There is no form to modify global to first match that I am aware of, so global vs first match would need to be separate statements.

只是我以为 2024-09-16 05:51:51

这是 Kinopiko 的回答和评估的组合。

这里使用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”组合将转到相同的键。

Here's a combination of Kinopiko's answer and eval.

eval is used here to generate the lookup table in a controlled and maintainable fashion, and a lookup table is used to save all the if.. elsif.. elsif which are not too fun to look at.

(very lightly tested)

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; 

To be fully useful this needs:

  1. combinations of possible modifiers
  2. sort function on the lookup table so 'msi' combination and 'mis' combination will go to the same key.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文