简体   繁体   English

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

[英]How do I use operations inside a Perl regex?

For example let's say I have something like this: 例如,假设我有这样的事情:

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

should print 1. Basically, is it possible to use functions inside the regex string? 应该打印1.基本上可以在正则表达式字符串中使用函数吗?

Variable interpolation in regexes works pretty much the same as variable interpolation in strings. 正则表达式中的变量插值与字符串中的变量插值几乎相同。 Given my $x = 2 , the string "$x $x+1" would be "2 2+1" . 给定my $x = 2 ,字符串"$x $x+1"将为"2 2+1" The variable is expanded, but code in the string is not executed. 变量被展开,但是字符串中的代码未执行。

One trick around this is to use dereference a reference inside the string. 解决此问题的一个技巧是在字符串内部使用对引用的取消引用。 This allows us to include arbitrary expressions, but the syntax is a bit cumbersome. 这允许我们包含任意表达式,但是语法有点麻烦。 Usually, we create an array reference with the value we want to include [$x + 1] , then immediately dereference it: @{[$x + 1]} . 通常,我们使用想要包含[$x + 1]的值创建一个数组引用,然后立即取消引用: @{[$x + 1]} This is similar to Ruby's #{...} interpolation, or to Bash $(...) command substitution. 这类似于Ruby的#{...}插值,或Bash $(...)命令替换。

So the regex /$x @{[$x + 1]}/x would work. 因此,正则表达式/$x @{[$x + 1]}/x可以工作。

But in most cases, it's going to be much clearer to perform all calculations outside of the regex: 但是在大多数情况下,在正则表达式之外执行所有计算会变得更加清晰:

my $x = 2;
my $y = $x + 1;
/$x $y/x;

The Perl regex syntax also has syntax that can generate parts of the regex dynamically. Perl regex语法还具有可以动态生成部分regex的语法。 With variable interpolation as above the variable contents are interpolated, and then the regex is compiled. 通过上面的变量插值,对变量内容进行插值,然后编译正则表达式。 But advanced regexes may change the value of a variable during the pattern match. 但是高级正则表达式可能会在模式匹配期间更改变量的值。 These delayed regexes can be written with the (??{ ... }) syntax. 这些延迟的正则表达式可以用(??{ ... })语法编写。 Here: /$x (??{ $x + 1 })/x . 此处: /$x (??{ $x + 1 })/x However, this is a very advanced and error-prone regex feature. 但是,这是一个非常高级且容易出错的正则表达式功能。 This will also be slower than an ordinary regex. 这也将比普通的正则表达式慢。

There is an extended pattern that provides for code execution in the match operator m/ or in the matching part of the substitution operator s/// . 一个扩展的模式可以在匹配运算符m/或替换运算符s///的匹配部分中提供代码执行。

Its version that substitutes the code's return and goes on to treat it as a pattern is 它的版本代替了代码的返回,并继续将其视为模式

/(??{ code })/

so in your case 所以你的情况

$_ = 23;
my $x = 2;
my ($m) = /(2(??{ $x+1 }))/;
say $m;

or 要么

RE_EVAL: {
    use re 'eval';
    my ($m) = /($x(??{ $x+1 }))/;
    say $m;
}

matches and captures 23 . 匹配并捕获23

Here use re 'eval' specifically allows this, normally disallowed for security reasons. 这里使用re'eval'专门允许这样做,出于安全原因通常不允许这样做。

This is a very involved capability which comes with complex warnings. 这是一个非常复杂的功能,带有复杂的警告。 Apart from its entry at the above link also follow the link in that text and read about Embedded Code Execution frequency . 除了在上面的链接中输入其内容外,还请跟随该文本中的链接,并阅读有关嵌入式代码执行频率的信息

Please don't use this complex tool for convenience, or to substitute for properly written code. 为了方便起见,请勿使用此复杂工具,也不要使用正确编写的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM