pb1*_*149 31 regex perl modifier
我在理解这个简单使用/ e正则表达式修饰符时遇到了一些麻烦.
my $var = 'testing';
$_ = 'In this string we are $var the "e" modifier.';
s/(\$\w+)/$1/ee;
print;
Run Code Online (Sandbox Code Playgroud)
返回:"在这个字符串中,我们正在测试"e"修饰符."
我不明白为什么需要两个'e'修饰符.据我所知,$ 1应该从字符串中捕获'$ var',然后单个'e'修饰符应该能够用它的值替换变量.但是我必须误解一些东西,因为只用一个'e'修饰符来尝试上面的代码并不会明显地替换字符串中的任何内容.
请问这么简单的问题!
谢谢.
tch*_*ist 39
这不是一个"简单"的问题,所以不要打败自己.
问题在于,单一/e
的RHS被理解为代码,其eval
结果用于替换.
什么是RHS?是的$1
.如果您进行了评估$1
,则会发现它包含字符串 $var
.它不包含所述变量的内容, $
后面v
跟着一个a
后跟一个r
.
因此,你必须两次对其进行评估,一旦转$1
成$var
,然后再次把以前的结果$var
到字符串"testing"
.你可以通过ee
在s
运算符上使用double 修饰符来实现.
您可以通过一个/e
与两个一起运行它来轻松地检查它.这是一个演示两者,再加上第三种使用符号解除引用的方法 - 因为它引用了包符号表,所以只对包变量起作用.
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: ", $_;
}
Run Code Online (Sandbox Code Playgroud)
运行时,会产生:
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.
Run Code Online (Sandbox Code Playgroud)
要清楚,s//ee
表单根本不会修改正则表达式或正则表达式解释.在执行正则表达式之后,它是替换侧弦的可选处理.(参见PERLOP Regex报价操作员)
的e
或ee
刚刚获得混合到图案侧壁的正则表达式的选择s/PATTERN/REPLACEMENT/msixpodualgcer
形式.
来自Perlop:
选项与m //一样,添加了以下替换特定选项:
Run Code Online (Sandbox Code Playgroud)e Evaluate the right side as an expression. ee Evaluate the right side as a string then eval the result. r Return substitution and leave the original string untouched.
您可以在非正则表达式情况下看到相同的e
vs ee
类型行为,如此示例所示:
#!/usr/bin/perl
use warnings;
use strict;
my $var = "var's contents";
my $str='"-> $var <-"';
print eval('$str'), "\n"; # equivalent to s//e
print eval(eval('$str')), "\n"; # equivalent to s//ee
Run Code Online (Sandbox Code Playgroud)
输出:
"-> $var <-"
-> var's contents <-
Run Code Online (Sandbox Code Playgroud)