评估存储在变量perl regexp中的模式

时间:2012-10-17 12:54:45

标签: regex perl variables eval match

我试图找出篮子是否有苹果[大问题的简化版]

$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. 2.我还有一个包含许多此类水果的perl哈希的水果属性列表

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

    每行的水果数量/配置文件是否有更简单的方法来实现此目的?非常感谢

4 个答案:

答案 0 :(得分: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";
}

答案 1 :(得分:0)

为什么需要将语句存储在变量中?如果您确定该值未由用户设置,则可以执行

if (eval $check_fruit) {

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

答案 2 :(得分:0)

将模式(仅模式)放入变量中,使用匹配分隔符m/.../的正则表达式中的变量。如果您事先不知道该模式,请使用quotemeta来转义任何元字符。

它应该是这样的:

my $check_fruit = '/has/apple/'; # here no quotemeta is needed
my $fruit       = 'basket/has/mango/';
if ($fruit =~ m/$check_fruit/) {
  # do stuff!
}

答案 3 :(得分: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代码更具动态性。最好的方法取决于你想要完成的任务。

相关问题