Предупреждение о регулярном выражении perl: \ 1 лучше записать как $ 1 в строке (eval 1) 1 - PullRequest
3 голосов
/ 21 апреля 2011
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, но это не работает.Что я должен делать?Большое спасибо.

Ответы [ 3 ]

6 голосов
/ 21 апреля 2011

\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 голос
/ 22 апреля 2011

Я вижу много повторений в вашем коде.

Предполагая, что вы используете 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;
0 голосов
/ 21 апреля 2011

Если предположить, что шаблон вашей карты сопоставления с образцом остается прежним, почему бы не избавиться от него и просто сказать:

$line =~ s/\s*=.*/=$newPassword/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...