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

时间:2017-12-18 10:09:45

标签: regex perl

例如,让我说我有这样的事情:

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

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

2 个答案:

答案 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

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