in reply to "ee" in Regular Expression: version issue?
The short answer
The RHS of s/LHS/RHS/ undergoes a variable interpolation (like doublequotes) if and only if there are no /e modifiers used.
modifiers | substition | equivalent |
---|---|---|
no e | VAR =~ s/LHS/RHS/ | VAR =~ m/LHS/; MATCH = "RHS" |
one e | VAR =~ s/LHS/RHS/e | VAR =~ m/LHS/; MATCH = eval 'RHS' |
two e | VAR =~ s/LHS/RHS/ee | VAR =~ m/LHS/; MATCH = eval eval 'RHS' |
more e | Don't! Only for brainfuck and obfuscation, better call function |
MATCH meaning the substring from VAR matching the LHS-pattern.
For completeness nota bene ...
concept | code | equivalent |
---|---|---|
disabling interpolation | VAR =~ s'LHS'RHS' | VAR =~ m/LHS/; MATCH = 'RHS' |
string interpolation | $a = "$b - $c" | $a = $b . ' - ' . $c |
variable evaluation | $a = $b | $a = eval '$b' |
The long answer ...
Problem
At first it's confusing that there is no difference between s/(pattern)/$1/ and s/(pattern)/$1/e
example:
DB<1> $_='abc'; s/a(b)c/$1/; print $_ b DB<2> $_='abc'; s/a(b)c/$1/e; print $_ b
Explanation
Line 1 w/o e-modifier but with interpolation:
Variables in RHS undergo an interpolation like the result in double-quotes "RHS"!
the following code is equivalent
DB<1> $_='abc'; s/a(b)c/$1/; print $_ b DB<3> $_='abc'; m/a(b)c/; $_ = "$1" ; print $_ b
Line 2: with e-modifier but w/o interpolation:
RHS is evaluated without variable interpolation¹ like in simple quotes eval 'RHS'
DB<2> $_='abc'; s/a(b)c/$1/e; print $_ b DB<4> $_='abc'; m/a(b)c/; $_= eval '$1'; print $_ b
And $_= eval '$1' just means $_= $1
I hope now double evals /ee can be better understood
Like ikegami stated correctly those s/LHS/RHS/ee; and s/LHS/eval RHS/e; are equivalent
Those double /ee are used if you need a matchvariables (a substring from LHS) to be interpolated within an eval, b/c variable interpolation is missing!
Any code from LHS will be treated as uninterpolated string, as in these equivalent expamples
DB<5> $_='warn 666'; s/(.*)/$1/e; print $_ warn 666 DB<6> $_='warn 666'; m/(.*)/; $_= eval '$1'; print $_ warn 666
So if I need code-evaluation from parts of LHS I need a second /e
DB<7> $_='warn 666'; s/(.*)/$1/ee; print $_ 666 at (eval 171) .... # skipped error message 1 # $_ = return code from warn DB<8> $_='warn 666'; m/(.*)/; $_= eval eval '$1'; print $_ 666 at (eval 175). ... # skipped error message 1 # $_ = return code from warn
Resumee
I think this explanation could be better worded ...
It already helped me a lot to clarify whats happening and I hope it helps you too or anyone else who tries to explain it better. =)
Cheers Rolf
1) As a side note:
Variable interpolation is a powerful tool which allows some (not all) "evaluation like effects" like interpolation of hash-variables.
DB<134> $hash{b}=666; DB<135> $_='abc'; s/a(b)c/$hash{$1}/; print $_ 666 DB<136> $_='abc'; m/a(b)c/; print "$hash{$1}"; 666
|
---|