Personally, I don't see any need to improve on the old standard:
s/^\s+//;
s/\s+$//;
update: After seeing thinker's reply I realized I might have misunderstood the question. If, like he suggests, you mean to remove leading and trailing whitespace from each line of a multi-line string, then I'd change the second line above to:
s/\s*\n\s*/\n/g;
| [reply] [d/l] [select] |
s/^[^\S\n]+//gm;
s/[^\S\n]+$//gm;
ihb
See perltoc if you don't know which perldoc to read!
| [reply] [d/l] [select] |
Probably as good as it gets... Much better than my 1.cut at the job. Tanks a heap! Allan
| [reply] |
If you want to trim the leading and trailing whitespace from every line in a multiline string, you can use
s/^\s*(.*?)\s*$/$1/gm
cheers
thinker
| [reply] [d/l] |
yup, i may need that, Good to have on the shelf! Thanks, Allan
| [reply] |
Multiline, huh? You mean you want to trim every line independently?
s/^[\t\ ]+//gm;
s/[\t\ ]+$//gm;
I don't use \s because I want to leave the newlines alone.
| [reply] [d/l] |
Hi bart
In the example I gave above, s/^\s*(.*?)\s*$/$1/gm
the combination of the \m modifier, and the line anchors ^ and $ will ensure the newlines are left alone
cheers
thinker
| [reply] [d/l] [select] |
$_ = " no \n \n \n they \n \n won't \n\n\n";
s/^\s*(.*?)\s*$/$1/gm;
print;
Result:
no
they
won't
All blank lines are gone. | [reply] [d/l] |
| [reply] |
Here's a benchmark, using the mentioned single regex, the double regex from the FAQ (also mentioned), BrowserUKs solution, and the one from Regexp::Common:
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark 'cmpthese';
use Regexp::Common;
use Test::More tests => 4;
our @data = (
" White space in front",
"White space at back ",
"Nowhitespaceatall",
"White space, but not in front or at back",
" White space in front, and at back "
);
our @expected = (
"White space in front",
"White space at back",
"Nowhitespaceatall",
"White space, but not in front or at back",
"White space in front, and at back"
);
our (@s, @d, @b, @r);
print '#';
cmpthese -1, {
'#single' => '@s = @data; s/^\s*(.*?)\s*$/$1/s for @s',
'#duo' => '@d = @data; s/^\s+//, s/\s+$// for @d',
'#browseruk' => '@b = @data; s/^\s*(.*)\b\s*$/$1/s for @b',
'#R::C' => '@r = map {$RE{ws}{crop}->subs($_)} @data',
};
is_deeply (\@s, \@expected, "single");
is_deeply (\@d, \@expected, "duo");
is_deeply (\@b, \@expected, "browseruk");
is_deeply (\@r, \@expected, "R::C");
__END__
1..4
# Rate #R::C #single #browseruk #duo
#R::C 1914/s -- -87% -94% -97%
#single 15175/s 693% -- -53% -75%
#browseruk 32288/s 1587% 113% -- -46%
#duo 59650/s 3017% 293% 85% --
ok 1 - single
ok 2 - duo
ok 3 - browseruk
ok 4 - R::C
| [reply] [d/l] |
s[^\s*(.*)\b\s*$][$1]
Update: Corion rightly points out that this does not work correctly for lines where the last non whitespace character is a non-words character. Eg.
the quick brown fox ( \n
# ^
So, use s[^\s*(.*\S)\s*$][]; instead. It's slower, but still quicker than the FAQ method.
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco.
Rule 1 has a caveat! -- Who broke the cabal?
| [reply] [d/l] [select] |
Good one too (needs the gm modifiers to do the job tho') -- allan
| [reply] |
I'm surprised that everyone (including the FAQ) missed the most obvious solution which uses an alternation. Most other solutions seem to forget that the $ anchor is right before the trailing newline. :)
$string =~ s/^\s+|\s+$//gm;
If you want to preserve blank lines, it's a tiny bit longer.
s/^[\t\f ]+|[\t\f ]+$//mg;
Remember: in Perl, the common things are supposed to be easy, so if you're doing something common and it's not easy, you're probably missing something. :)
I'm going to update the FAQ answer too.
--
brian d foy <brian@stonehenge.com>
| [reply] [d/l] [select] |