I am not sure I understand what you want to do, but this removes spaces after numbers, but not before them:
#!/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;
The first substitution works by matching one or more non-whitespace characters ((\S+)
) followed by one or more spaces (+
) followed by the end of the line ($
) and replacing the match with $1
(which contains the match captured by the parenthesis, i.e. the non-whitespace characters). The /m
modifier makes $
match the end of line rather than the end of the string and the /g
makes it match as many times as it can (otherwise only the list line would be affected).
The second regex just replaces all of the spaces with periods to make it easier to see if the first regex was successful.
If you have Perl 5.10 or later, you can use the \K
escape rather than the capture to tell perl
you want to keep the stuff on the left hand side:
#!/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;
It is significantly faster than the capture. In this case, it is 83% faster:
#!/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;