Я не уверен, что понимаю, что вы хотите сделать, но это удаляет пробелы после чисел, но не перед ними:
#!/usr/bin/perl
use strict;
use warnings;
my $string =
"123 \n" . #these lines have spaces after the number
" 456 \n" .
" 573\n" . #these lines don't
" 763\n" .
" integer\n";
$string =~ s/(\S+) +$/$1/gm;
$string =~ s/ /./g; #make the spaces visible as periods
print $string;
Первая замена работает путем сопоставления одного или нескольких непробельных символов ((\S+)
), за которым следуют один или несколько пробелов (+
), за которыми следует конец строки ($
) и замена совпадения на $1
(которое содержит совпадение, захваченное скобками, то есть непробельный пробел)персонажи).Модификатор /m
заставляет $
совпадать с концом строки, а не с концом строки, а /g
заставляет его совпадать столько раз, сколько может (иначе это затронет только строку списка).
Второе регулярное выражение просто заменяет все пробелы точками, чтобы было легче увидеть, было ли первое регулярное выражение успешным.
Если у вас есть Perl 5.10 или более поздняя версия, вы можете использовать экранирование \K
вместопри захвате укажите perl
о том, что вы хотите сохранить материал с левой стороны:
#!/usr/bin/perl
use strict;
use warnings;
my $string =
"123 \n" . #these lines have spaces after the number
" 456 \n" .
" 573\n" . #these lines don't
" 763\n" .
" integer\n";
$string =~ s/\S+\K +$//gm;
$string =~ s/ /./g; #make the spaces visible as periods
print $string;
Это значительно быстрее, чем при захвате.В этом случае это на 83% быстрее:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;
my $s =
"123 \n" . #these lines have spaces after the number
" 456 \n" .
" 573\n" . #these lines don't
" 763\n" .
" integer\n";
my %subs = (
keep => sub {
my $t = $s;
$t =~ s/\S+\K +$//gm;
return $t;
},
capture => sub {
my $t = $s;
$t =~ s/(\S+) +$/$1/gm;
return $t;
},
);
for my $sub (keys %subs) {
print "$sub: ", $subs{$sub}(), "\n";
}
Benchmark::cmpthese -1, \%subs;