简体   繁体   English

perl操作员s /// e未能按预期工作

[英]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/es/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+341替换)并递增$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM