views:

93

answers:

2

Normally if you wish to change a variable with regex you do this:

$string =~ s/matchCase/changeCase/; 

But is there a way to simply do the replace inline without setting it back to the variable?

I wish to use it in something like this:

my $name="jason";
print "Your name without spaces is: " $name => (/\s+/''/g);

Something like that, kind of like the preg_replace function in PHP.

+4  A: 

You can use map and a lexical variable.

my $name=" jason ";

print "Your name without spaces is: ["
    , ( map { my $a = $_; $a =~ s/\s+//g; $a } ( $name ))
    , "]\n";

Now, you have to use a lexical because $_ will alias and thus modify your variable.

The output is

Your name without spaces is: [jason]
# but: $name still ' jason '

Admittedly do will work just as well (and perhaps better)

print "Your name without spaces is: ["
    , do { my ( $a = $name ) =~ s/\s+//g; $a }
    , "]\n";

But the lexical copying is still there. The assignment within in the my is an abbreviation that some people prefer (not me).

For this idiom, I have developed an operator I call filter:

sub filter (&@) { 
    my $block = shift;
    if ( wantarray ) { 
        return map { &$block; $_ } @_ ? @_ : $_;
    }
    else { 
       local $_ = shift || $_;
       $block->( $_ );
       return $_;
    }
}

And you call it like so:

print "Your name without spaces is: [", ( filter { s/\s+//g }, $name )
    , "]\n";
Axeman
Or you could use a lexical variable without using `map`: `print "Your name without spaces is: [", do{my $a=$name; $a=~s/\s+//g; $a}, "]\n"`
mobrule
@mobrule:I was adding that as you typed. :D
Axeman
Accepted this one since it has more explanation.
Razor Storm
+1  A: 
print "Your name without spaces is: @{[map { s/\s+//g; $_ } $name]}\n";
Greg Bacon