0

我想知道篮子里有没有苹果[大问题的简化版]

$check_fruit = "\$fruit =~ \/has\/apple\/";
$fruit="basket/has/mango/";
if ($check_fruit) {
       print "apple found\n";
}

check_fruit 变量持有评估正则表达式的语句。然而它 check_fruit 变量总是变为真并显示苹果找到:(

如果我遗漏了什么,有人可以在这里帮助我。

要完成的目标:好的,让我解释一下:

  1. 我有一个文件,其中在每一行上定义了一个模式子句,类似于:

    Line1: $fruit_origin=~/europe\\/finland/ && $fruit_taste=~/sweet/ 
    Line2: similar stuff that can contain ~10 pattern checks seprated by && or || with metacharacters too 
    

2.我有另一个来自 perl 哈希的水果属性列表,其中包含许多这样的水果

3 我想对每个水果进行分类,看看有多少水果分别属于文件每一行定义的类别。

每行水果计数/配置文件的排序有没有更简单的方法来完成这个?非常感谢

4

4 回答 4

2

if ($check_fruit)返回 true 因为 $check_fruit 已定义,不为空也不为零。如果要评估其内容,请使用eval. 但是子程序会更好:

sub check_fruit {
    my $fruit = shift;
    return $fruit =~ m(has/apple);
}

if (check_fruit($fruit)) {
    print "Apple found\n";
}
于 2012-10-17T12:59:02.460 回答
0

$check_fruit只不过是一个保存字符串数据的变量。如果你想执行它包含的代码,你必须使用eval.

您的代码中还有一些与字符串引用/转义相关的其他错误。这也解决了这个问题:

use strict;
use warnings;
my $check_fruit = '$apple =~ m|/has/mango|';
my $apple="basket/has/mango/";

if (eval $check_fruit) {
       print "apple found\n";
}

然而,这通常不是一个好的设计。至少,它会使代码混乱。$check_fruit如果来自用户,这也是一个巨大的安全漏洞。您可以将正则表达式放入变量中,这是可取的:

编辑:请注意,来自用户输入的正则表达式也可能是一个安全问题,但范围更有限。

my $check_fruit = qr|/has/mango|;
my $apple="basket/has/mango/";

if ($apple =~ /$check_fruit/) {
       print "apple found\n";
}

您还可以做其他事情来使您的 Perl 代码更加动态。最好的方法取决于您要完成的工作。

于 2012-10-17T13:04:57.043 回答
0

为什么需要将语句存储在变量中?如果您确定该值不是由用户设置的,那么您可以这样做

if (eval $check_fruit) {

但如果用户可以在该表达式中设置任何内容,则这是不安全的。

于 2012-10-17T12:58:44.580 回答
0

将模式(并且只有模式)放入变量中,使用正则表达式匹配 delimiters 中的变量m/.../。如果您事先不知道该模式,则quotemeta用于转义任何元字符。

它应该如下所示:

my $check_fruit = '/has/apple/'; # here no quotemeta is needed
my $fruit       = 'basket/has/mango/';
if ($fruit =~ m/$check_fruit/) {
  # do stuff!
}
于 2012-10-17T12:59:11.447 回答