use strict;
use warnings;
my $newPasswd = 'abc123';
my @lines = ( "pwd = abc", "pwd=abc", "password=def", "name= Mike" );
my %passwordMap = (
'pwd(\\s*)=.*' => 'pwd\\1= $newPasswd',
'password(\\s*)=.*' => 'password\\1= $newPasswd',
);
print "@lines\n";
foreach my $line (@lines) {
while ( my ( $key, $value ) = each(%passwordMap) ) {
if ( $line =~ /$key/ ) {
my $cmdStr = "\$line =~ s/$key/$value/";
print "$cmdStr\n";
eval($cmdStr);
last;
}
}
}
print "@lines";
运行它会给我正确的结果:
pwd = abc pwd=abc password=def name= Mike
$line =~ s/pwd(\s*)=.*/pwd\1= $newPasswd/
\1 better written as $1 at (eval 2) line 1 (#1)
$line =~ s/password(\s*)=.*/password\1= $newPasswd/
\1 better written as $1 at (eval 3) line 1 (#1)
pwd = abc123 pwd=abc password= abc123 name= Mike
我不想看到警告,试图使用$ 1而不是\ 1,但它不起作用。我该怎么办?非常感谢。
答案 0 :(得分:6)
\1
是一个正则表达式,意思是“匹配第一组捕获的parens捕获的内容。”在替换表达式中使用它是完全没有意义的。要获取第一组捕获parens捕获的字符串,请使用$1
。
$line =~ s/pwd(\s*)=.*/pwd\1= $newPasswd/
应该是
$line =~ s/pwd(\s*)=.*/pwd$1= $newPasswd/
所以
'pwd(\\s*)=.*' => 'pwd\\1= $newPasswd',
'password(\\s*)=.*' => 'password\\1= $newPasswd',
应该是
'pwd(\\s*)=.*' => 'pwd$1= $newPasswd',
'password(\\s*)=.*' => 'password$1= $newPasswd',
或更好
qr/((?:pwd|password)\s*=).*/ => '$1= $newPasswd',
答案 1 :(得分:1)
我看到你的代码中有很多重复。
假设您使用的是Perl 5.10或更高版本,这就是我编写代码的方式。
use strict;
use warnings;
use 5.010;
my $new_pass = 'abc123';
my @lines = ( "pwd = abc", "pwd=abc", "password=def", "name= Mike" );
my @match = qw'pwd password';
my $match = '(?:'.join( '|', @match ).')';
say for @lines;
say '';
s/$match \s* = \K .* /$new_pass/x for @lines;
# which is essentially the same as:
# s/($match \s* =) .* /$1$new_pass/x for @lines;
say for @lines;
答案 2 :(得分:0)
假设您的模式匹配地图的模式保持不变,为什么不摆脱它并简单地说:
$line =~ s/\s*=.*/=$newPassword/