有沒有辦法在替換中使用變量作爲修飾符?如何在替換中使用變量作爲修飾符
my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'ee';
s/$search/$replace/$modifier;
我需要使用散列數組進行批量搜索 - 用不同的修飾符進行替換。
有沒有辦法在替換中使用變量作爲修飾符?如何在替換中使用變量作爲修飾符
my $search = 'looking';
my $replace = '"find: $1 ="';
my $modifier = 'ee';
s/$search/$replace/$modifier;
我需要使用散列數組進行批量搜索 - 用不同的修飾符進行替換。
嗯,如果我不得不這樣做,我會做這樣的:
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
這個,但它非常混亂。
如果您戴上安全護目鏡和零分服裝,則可以使用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]: [email protected]" 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";
我的零分錢套裝在它的無窮大附近有一個洞 – Borodin 2015-06-12 08:04:58
在使用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
當然s/$search/$replace/
按照您的預期工作。這是動態修飾符,不直截了當。
對於常規匹配modifierspimsx
,您可以使用Perl的Extended Patterns作爲模式的一部分即時修改修飾符標誌。這些格式爲(?pimsx-imsx)
可打開/關閉這些修改器。
對於s//
e
和ee
表單,您可以使用(?{ perl code})
記錄在同一個perlre部分。對於所有eval
e
或ee
表單,請考慮結果代碼的安全性!
沒有任何形式可以修改我知道的全局匹配,所以全局匹配和第一次匹配需要單獨的語句。
下面是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;
爲了這需要充分有用:可能改性劑
或者只是將修飾符驗證檢查添加到其他評估答案,例如現在的答案。 – runrig 2010-07-14 15:43:49
某些修飾符可以在「正則表達式」中作爲'(?modifier:pattern)'提供,但不能影響整個事物,如/ g或/ e。這是「你爲什麼要這樣做」的時刻之一。如果你告訴我們這是爲了什麼,我們可能會想出一個更簡單的方法,而不是刷駱駝毛(並打開安全孔)。 – Schwern 2010-07-13 18:50:42
@Schwern:如果你在駱駝上開一個洞,這是最讓人不愉快的事 – Borodin 2015-06-12 08:06:47