Charles Charles - 2 months ago 5x
Perl Question

Inline regex replacement in perl

Is there a way to replace text with a regex inline, rather than taking the text from a variable and storing it in a variable?

I'm a perl beginner. I often find myself writing

my $foo = $bar;
$foo =~ s/regex/replacement/;

where I'd really like to write


or the like, rather than using a temporary variable and three lines.

Is there a way to do this? Obviously when the regex is sufficiently complicated it makes sense to split it out so it can be better explained, but when it's just
it feels wrong to clutter the code with additional variables.


You really can't do what you want because the substitution function returns either a 1 if it worked or an empty string if it didn't work. That means if you did this:

doStuff($foo =~ s/regex/replacement/);

The doStuff function would be using either 1 or an empty string as a parameter. There is no reason why the substitution function couldn't return the resultant string instead of just a 1 if it worked. However, it was a design decision from the earliest days of Perl. Otherwise, what would happen with this?

$foo = "widget";
if ($foo =~ s/red/blue/) {
    print "We only sell blue stuff and not red stuff!\n";

The resulting string is still widget, but the substitution actually failed. However, if the substitution returned the resulting string and not an empty string, the if would still be true.

Then, consider this case:

$bar = "FOO!";
if ($bar =~ s/FOO!//) {
   print "Fixed up \'\$bar\'!\n";

$bar is now an empty string. If the substitution returned the result, it would return an empty string. Yet, the substitution actually succeeded and I want to my if to be true.

In most languages, the substitution function returns the resulting string, and you'd have to do something like this:

if ($bar != replace("$bar", "/FOO!//")) {
   print "Fixed up \'\$bar''!\n";

So, because of a Perl design decision (basically to better mimic awk syntax), there's no easy way to do what you want. However you could have done this:

($foo = $bar) =~ s/regex/replacement/;

That would do an in place setting of $foo without first assigning it the value of $bar. $bar would remain unchanged.