如何在Perl中评估字符串中的链式表达式?

时间:2009-12-01 07:00:32

标签: perl conditional eval

我不确定该怎么称呼这些类型的表达式,所以一个例子会更容易......

Perl有没有办法评估像a < b <= c这样的表达式?我有一个配置文件,允许用户为某些操作提供条件表达式。而不是将条件分成两部分(正如我通常在代码中所做的那样),如果可能的话,我想以这种方式表示它。

5 个答案:

答案 0 :(得分:2)

这肯定是在Perl 6中出现的。但不幸的是,我认为这不是Perl 6借用Perl 5.10的东西之一。

答案 1 :(得分:2)

Perl 6中提供了

Chained comparisons

现在,would it be possible to create a daisy-chaining sub-routine for Perl 5.x?这是一个有趣的问题......

答案 2 :(得分:0)

这可读性稍差,但可以实现您的目标:a < b && b <= c

答案 3 :(得分:0)

正如其他人所说,Perl5尚未进行链接比较。

但是,如果您正在从配置文件中解析“a&lt; b&lt; = c”并且只想评估它,那么也许这可能是您的转向之后的事情?

use strict;
use warnings;
use 5.010;

my ($a, $b, $c) = (10, 20, 30);

say 'Its true!'  if comparison( $a, '<', $b, '<=', $c );

sub comparison {
    my $left = shift;

    while (my $cmp = shift) {
        my $right = shift;
        compare( $cmp, $left, $right ) or return;
        $left = $right;
    }

    return 1;
}

sub compare {
    my $op = shift;
    given ($op) {
        when ( '<'  ) { return $_[0] <  $_[1] }
        when ( '<=' ) { return $_[0] <= $_[1] }
        default       { die "Invalid comparison operator" }
    }
}

它只是一个基本的例子(即不完整,没有错误检查),但我认为你明白了。

你可能已经在CPAN找到了类似的东西。像Parse::RPN之类的东西可能是一个有用的构建块。

现在,如果你质疑的是如何逐字解析a < b <= c那么这就是另一条鱼!

/ I3az /

答案 4 :(得分:0)

忽略任何输入验证或暂时执行最终比较,以下代码(或其中的一个小变体)应该能够重写您的语句:

sub rewrite {
    my $str = shift;
    my $ops = join "|" => qw/ < > <= >= == != /;
    1 while $str =~ s/ ($ops) \s* (\w+?) \s* ($ops) /$1 $2 && $2 $3/xg;
    $str
}

print rewrite "a < b < 5 < c != d";
# prints a < b && b < 5 && 5 < c && c != d