如何在Perl正则表达式中使用操作?

问题描述 投票:0回答:2

例如,假设我有这样的事情:

 $_ = 23;
 $a = 2;
 print /$a $a+1/x;

应该打印1.基本上,是否可以在正则表达式字符串中使用函数?

regex perl
2个回答
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
投票

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的内容。

为方便起见,请不要使用这个复杂的工具,或者替换正确编写的代码。

© www.soinside.com 2019 - 2024. All rights reserved.