Is there a Perl-compatible regular expression to trim whitespace from both sides of a string?

My first question is ... why? I don't see any of the single-regexp solutions to be any more readable than the regexp you started with. And they sure aren't anywhere near as fast.

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw(:all);

my $a = 'a' x 1_000;

my @x = (
         "    $a   ",
         "$a   ",
         $a,
         "    $a"
        );

cmpthese(-5,
         {
             single => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/^\s+|\s+$//g;
                 }
             },
             double => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/^\s+//;
                     $x =~ s/\s+$//;
                 }
             },
             trick => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     s/^\s+//, s/\s+$// for $x;
                 }
             },
             capture => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/\A\s*(.*?)\s*\z/$1/
                 }
             },
             kramercap => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     ($x) = $x =~ /^\s*(.*?)\s*$/
                 }
             },
         }
        );

gives results on my machine of:

             Rate    single   capture kramercap     trick    double
single     2541/s        --      -12%      -13%      -96%      -96%
capture    2902/s       14%        --       -0%      -95%      -96%
kramercap  2911/s       15%        0%        --      -95%      -96%
trick     60381/s     2276%     1981%     1974%        --       -7%
double    65162/s     2464%     2145%     2138%        8%        --

Edit: runrig is right, but to little change. I've updated the code to copy the string before modification, which, of course, slows things down. I also took into account brian d foy's suggestion in another answer to use a longer string (though a million seemed like overkill). However, that also suggests that before you choose the trick style, you figure out what your string lengths are like - the advantages of trick are lessened with shorter strings. At all lengths I've tested, though, double wins. And it's still easier on the eyes.


$x =~ s/^\s+|\s+$//g;

or

s/^\s+//, s/\s+$// for $x;

Funny you should bring this up!

I recently read an article analyzing the performance of twelve (!) different trim implementations.

Although the article specifically uses the JavaScript regex implementation, it uses Perl syntax, so I think it's apropos to this discussion.