perl运营商/// e没有按预期工作

Ora*_*bîg 0 regex syntax perl

我试图弄清楚为什么这样做:

 $_='12+34';$x=1;
 s/(\d+)(.)(\d+)/"\$x$2$2"/ee; # This is working, does $x++

 print "x=$x \n";              # x=2
Run Code Online (Sandbox Code Playgroud)

虽然这不是:

 $_='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?)
Run Code Online (Sandbox Code Playgroud)

我有勇气s/xxx/yyy/e并且s/xxx/"yyy"/ee应该表现得一样,但显然我错了.

我错过了什么?

Bor*_*din 7

你误解了表达式修饰符 - 单个/e

它导致替换字符串被视为Perl表达式,并且本质上是标准模式的替代方法,它将处理字符串,就好像它是双引号一样

一般

my $x = 1;
my $y = '12+34';

$y =~ s/(\d+)(.)(\d+)/\$x$2$2/;
Run Code Online (Sandbox Code Playgroud)

产生等同于字符串的替换qq{\$x$2$2},即$x++

如果你添加一个/e然后替换被视为Perl表达式,并且你得到错误,因为\$x$2$2无效的Perl.您可以通过使用获得与以前相同的结果

s/(\d+)(.)(\d+)/'$x' . $2 . $2/e
Run Code Online (Sandbox Code Playgroud)

或者,正如您所见,字符串表达式

s/(\d+)(.)(\d+)/"\$x$2$2"/e
Run Code Online (Sandbox Code Playgroud)

但所有这些都是评估Perl表达式.没有办法执行从目标字符串的部分构造的任意Perl代码而不添加/e代表eval的第二个修饰符

结果/ee导致Perl将替换视为表达式(而不是对其进行双引号插值)然后评估该表达式的结果

例如

s/(\d+)(.)(\d+)/'$x' . $2 . $2/ee
Run Code Online (Sandbox Code Playgroud)

首先计算表达式'$x' . $2 . $2给出$x++,然后eval对该字符串进行计算,返回1(因此原始12+34替换为1)并递增$x

如果您可以编写满足您需要的Perl表达式,则可以将表达式模式与单个表达式一起使用/e.否则你也需要用来/ee获得一个eval阶段

如果您参与其中/e,我认为使用牙箍更清楚.这样它看起来像Perl代码而不是字符串替换

s{(\d+)(.)(\d+)}{
    '$x' . $2 . $2
}ee
Run Code Online (Sandbox Code Playgroud)

  • @Orabîg:没错.`s/pattern/replacement /`与`s/pattern/qq {replacement}/e`相同 (2认同)