Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Regex 'e' (eval) modifier with s///

I'm having a little trouble comprehending this simple use of the /e regex modifier.

my $var = 'testing'; $_ = 'In this string we are $var the "e" modifier.';  s/(\$\w+)/$1/ee;  print; 

Returns: "In this string we are testing the "e" modifier."

I cannot see why two 'e' modifiers are required. As far as I can see, $1 should capture '$var' from the string and a single 'e' modifier should then be able to replace the variable with its value. I must be misunderstanding something however, since trying the above code with just one 'e' modifier does not visibly replace anything in the string.

Excuse me for asking such a simple question!

Thanks.

like image 559
pb149 Avatar asked May 21 '11 14:05

pb149


People also ask

What is S in Perl regex?

The Substitution Operator The substitution operator, s///, is really just an extension of the match operator that allows you to replace the text matched with some new text. The basic form of the operator is − s/PATTERN/REPLACEMENT/;

What does S * mean in Perl?

Substitution Operator or 's' operator in Perl is used to substitute a text of the string with some pattern specified by the user. Syntax: s/text/pattern.

What does \d mean in Perl?

The Special Character Classes in Perl are as follows: Digit \d[0-9]: The \d is used to match any digit character and its equivalent to [0-9]. In the regex /\d/ will match a single digit. The \d is standardized to “digit”. The main advantage is that the user can easily write in shorter form and can easily read it.

What is EE in regex?

In the above code, the expression is written in Regex using the '\d+' operator for writing one or more digits, [+*/-] character class for operator symbol, and then again a '\d+' for digit. The 'ee' modifier evaluates the string and returns the sum of the expression which is then printed using the $1 operator.


1 Answers

It’s not exactly a “simple” question, so don’t beat yourself up.

The issue is that with a single /e, the RHS is understood to be code whose eval’d result is used for the replacement.

What is that RHS? It’s $1. If you evaluated $1, you find that contains the string $var. It does not contain the contents of said variable, just $ followed by a v followed by an a followed by an r.

Therefore you must evaluate it twice, once to turn $1 into $var, then again to turn the previous result of $var into the string "testing". You do that by having the double ee modifier on the s operator.

You can check this pretty easily by running it with one /e versus with two of them. Here’s a demo a both, plus a third way that uses symbolic dereferencing — which, because it references the package symbol table, works on package variables only.

use v5.10;  our $str = q(In this string we are $var the "e" modifier.); our $var = q(testing);  V1: {     local $_ = $str;      s/(\$\w+)/$1/e;     say "version 1: ", $_;  }  V2: {     local $_ = $str;     s/(\$\w+)/$1/ee;     say "version 2: ", $_; }  V3: {     no strict "refs";     local $_ = $str;     s/\$(\w+)/$$1/e;     say "version 3: ", $_; } 

When run, that produces:

version 1: In this string we are $var the "e" modifier. version 2: In this string we are testing the "e" modifier. version 3: In this string we are testing the "e" modifier. 
like image 139
tchrist Avatar answered Oct 17 '22 08:10

tchrist