0

バスケットにリンゴがあるかどうかを調べようとしています [大問題の簡易版]

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

check_fruit 変数は、正規表現を評価するステートメントを保持しています。ただし、check_fruit変数は常にtrueになり、リンゴが見つかったことを示します:(

何か不足している場合は、誰かがここで私を助けてくれますか?

達成する目標: では、説明させてください。

  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)$check_fruit が定義されており、空でもゼロでもないため、true を返します。その内容を評価したい場合は、 を使用します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

ステートメントを変数に格納する必要があるのはなぜですか?値がユーザーによって設定されていないことが確実な場合は、次のことができます。

if (eval $check_fruit) {

しかし、ユーザーがその式に何かを設定できる場合、これは安全ではありません。

于 2012-10-17T12:58:44.580 に答える
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

パターン (およびパターンのみ) を変数に入れ、区切り文字に一致する正規表現内で変数を使用します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 に答える