例如,让我说我有这样的事情:
$_ = 23;
$a = 2;
print /$a $a+1/x;
应该打印1.基本上,是否可以在正则表达式字符串中使用函数?
答案 0 :(得分:1)
正则表达式中的变量插值与字符串中的变量插值几乎相同。给定my $x = 2
,字符串"$x $x+1"
将为"2 2+1"
。变量已扩展,但字符串中的代码未执行。
围绕这一点的一个技巧是在字符串中使用取消引用引用。这允许我们包含任意表达式,但语法有点麻烦。通常,我们使用要包含[$x + 1]
的值创建数组引用,然后立即取消引用它:@{[$x + 1]}
。这与Ruby的#{...}
插值或Bash $(...)
命令替换类似。
因此正则表达式/$x @{[$x + 1]}/x
可以正常工作。
但在大多数情况下,在正则表达式之外执行所有计算会更清楚:
my $x = 2;
my $y = $x + 1;
/$x $y/x;
Perl正则表达式语法还具有可以动态生成正则表达式部分的语法。通过如上所述的变量插值,内插变量内容,然后编译正则表达式。但是高级正则表达式可能会在模式匹配期间更改变量的值。这些延迟的正则表达式可以使用(??{ ... })
语法编写。在这里:/$x (??{ $x + 1 })/x
。但是,这是一个非常先进且容易出错的正则表达式功能。这也比普通的正则表达式慢。
答案 1 :(得分:1)
an extended pattern提供了匹配运算符m/
或替换运算符s///
的匹配部分中的代码执行。
它的版本替代了代码的返回并继续将其视为一种模式
/(??{ code })/
所以在你的情况下
$_ = 23;
my $x = 2;
my ($m) = /(2(??{ $x+1 }))/;
say $m;
或
RE_EVAL: {
use re 'eval';
my ($m) = /($x(??{ $x+1 }))/;
say $m;
}
匹配并捕获23
。
此处use re 'eval'明确允许此操作,但出于安全原因通常不允许这样做。
这是一个非常复杂的功能,伴随着复杂的警告。除了在上述链接中输入外,还请点击该文字中的链接,并阅读Embedded Code Execution frequency。
为方便起见,请不要使用此复杂工具,或替换正确编写的代码。