[英]perl operator s///e not working as expected
I'm trying to figure out why this is working : 我试图找出为什么这是可行的:
$_='12+34';$x=1;
s/(\d+)(.)(\d+)/"\$x$2$2"/ee; # This is working, does $x++
print "x=$x \n"; # x=2
while this is not : 虽然不是:
$_='12+34';$x=1;
s/(\d+)(.)(\d+)/\$x$2$2/e; # This is NOT working
# Error message is :
# Scalar found where operator expected at ./test.pl line 2, near "$x$2"
# (Missing operator before $2?)
I have the guts that s/xxx/yyy/e
and s/xxx/"yyy"/ee
should behave the same, but obviously I'm wrong. 我有胆量认为
s/xxx/yyy/e
和s/xxx/"yyy"/ee
行为应该相同,但显然我错了。
What am I missing ? 我想念什么?
You're misunderstanding the expression modifier -- a single /e
您误解了表达式修饰符-一个
/e
It causes the replacement string to be treated as a Perl expression, and is essentially an alternative to the standard mode, which is to process the string as if it were in double-quotes 它使替换字符串被视为Perl表达式,并且本质上是标准模式的替代方法,该模式将字符串当作双引号来处理
Normally 一般
my $x = 1;
my $y = '12+34';
$y =~ s/(\d+)(.)(\d+)/\$x$2$2/;
produces a replacement equivalent to the string qq{\\$x$2$2}
, which is $x++
产生等效于字符串
qq{\\$x$2$2}
的替换项,即$x++
If you add an /e
then the replacement is treated as a Perl expression, and you are getting errors because \\$x$2$2
isn't valid Perl. 如果添加
/e
则替换项将被视为Perl表达式,并且由于\\$x$2$2
无效的Perl而导致错误。 You could get the same result as before by using 通过使用,您可以获得与以前相同的结果
s/(\d+)(.)(\d+)/'$x' . $2 . $2/e
or, as you have seen, the string expression 或者,如您所见,字符串表达式
s/(\d+)(.)(\d+)/"\$x$2$2"/e
But all these do is evaluate the Perl expression. 但是所有这些都是评估Perl表达式。 There is no way to execute arbitrary Perl code that is constructed from parts of the target string without adding a second
/e
modifier which stands for eval 如果不添加第二个代表eval的
/e
修饰符,就无法执行由目标字符串的各个部分构成的任意Perl代码。
The resulting /ee
causes Perl to treat the replacement as an expression (instead of doing double-quote interpolation on it) and then eval the result of that expression 生成的
/ee
导致Perl将替换项视为表达式 (而不是对其进行双引号插值),然后评估该表达式的结果
For instance 例如
s/(\d+)(.)(\d+)/'$x' . $2 . $2/ee
first evaluates the expression '$x' . $2 . $2
首先计算表达式
'$x' . $2 . $2
'$x' . $2 . $2
'$x' . $2 . $2
giving $x++
and then does eval
on that string, returning 1 (so the original 12+34
is replaced with 1
) and incrementing $x
'$x' . $2 . $2
给出$x++
,然后对该字符串进行eval
,返回1(因此原来的12+34
被1
替换)并递增$x
You can use expression mode with a single /e
if you can write a Perl expression that does what you need. 如果可以编写满足您需要的Perl表达式,则可以将表达式模式与
/e
一起使用。 Otherwise you need to use /ee
to get an eval stage as well 否则,您也需要使用
/ee
获得评估阶段
I think it's clearer to use braces if you involve /e
at all. 我认为,如果您完全涉及
/e
,则使用大括号会更清楚。 That way it looks like Perl code and not a string replacement 这样,它看起来像Perl代码,而不是字符串替换
s{(\d+)(.)(\d+)}{
'$x' . $2 . $2
}ee
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.