Perl 正则表达式警告:\1 最好在 (eval 1) 第 1 行写为 $1

发布于 2024-11-02 11:07:06 字数 959 浏览 1 评论 0原文

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,但它不起作用。我应该怎么办?多谢。

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";

run it will give me the correct results:

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

I don't want to see the warnings, tried to use $1 instead of \1, but it does not work. What should I do? Thanks a lot.

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

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

发布评论

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

评论(3

清风无影 2024-11-09 11:07:06

\1 是一个正则表达式模式,表示“匹配第一组捕获括号捕获的内容”。在替换表达式中使用它绝对没有意义。要获取第一组捕获括号捕获的字符串,请使用$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 is a regex pattern that means "match what was captured by the first set of capturing parens." It makes absolutely no sense to use that in a replacement expression. To get the string captured by the first set of capturing parens, use $1.

$line =~ s/pwd(\s*)=.*/pwd\1= $newPasswd/

should be

$line =~ s/pwd(\s*)=.*/pwd$1= $newPasswd/

so

'pwd(\\s*)=.*'      => 'pwd\\1= $newPasswd',
'password(\\s*)=.*' => 'password\\1= $newPasswd',

should be

'pwd(\\s*)=.*'      => 'pwd$1= $newPasswd',
'password(\\s*)=.*' => 'password$1= $newPasswd',

or better yet

qr/((?:pwd|password)\s*=).*/ => '$1= $newPasswd',
爱的故事 2024-11-09 11:07:06

我在您的代码中看到很多重复。

假设您使用 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;

I see a lot of repetition in your code.

Assuming you're using Perl 5.10 or later, this is how I would have written your code.

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;
等待我真够勒 2024-11-09 11:07:06

假设你的模式匹配图的模式保持不变,为什么不摆脱它并简单地说:

$line =~ s/\s*=.*/=$newPassword/

Assuming that the pattern of your pattern matching map stays the same, why not get rid of it and say simply:

$line =~ s/\s*=.*/=$newPassword/
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文