2016-02-17 56 views
0

語境:如何最好地dynamcially準備和運行用戶提供的Perl運營商

Perl腳本初始化自身根據用戶提供PARAM文件,然後作用於用戶提供源文件來過濾數據並執行其他操作。

PARAM文件文件包含局部perl的表達,這將在後面假設是在運行時期間eval版,例如:

match:!~ col:1 operand:1|2|3 
match:=~ col:1 operand:[^123] 
match:=! col:1 operand:^DATE 
match:=~ col:1 operand:^(?:\s|DATE) 
match:-~ col:1 operand:^\s 
match:eq col:7 operand:CA 
match:eq col:7 operand:DI 
match:ne col:1 operand:ACCOUNT 
match:ne col:1 operand:POSITIONS 
match:== col:8 operand:999 
match:!= col:8 operand:999 

嗯,以及怎麼樣這樣的?也許以後,但我需要太

match="ne list" '11, 71, 7' 

簡單地說,我的Perl會得到用戶的匹配運算,然後需要從基於其他PARAMS的源文件過濾掉(或)記錄。

一個簡單的辦法,就是eval

next unless eval "$value $match $operand"; 

。現在,因爲我知道$match將始終是相同的,對源文件的每個輸入使用eval,聽起來像一個矯枉過正。

if ($match eq '!~') 
{ 
    next unless $value !~ /$operand/o; 
} 
elsif ($match eq '=~') 
{ 
    next unless $value =~ /$operand/o; 
} 
elsif ($match eq 'eq') 
{ 
    next unless $value eq $operand; 
} 
... 

而我正在考慮有一個哈希查找,不知道該怎麼做。 (我也想知道),也想到關閉...

我正在尋找最好和最有效的方法?

+1

使用'eval'是最少維護的代碼。參見[Eval :: Compile](http://search.cpan.org/dist/Eval-Compile-0.10/lib/Eval/Compile.pm)和[這個問題](http://stackoverflow.com/questions/ 24911132/perl-speeding-up-eval)關於加速eval。 – Kenney

+2

我不確定有沒有理由使用'/ o'。在這裏使用它是沒有意義的。 – ikegami

+0

@ikegami我看到[你的觀點](http://stackoverflow.com/questions/550258/does-the-o-modifier-for-perl-regular-expressions-still-provide-any-benefit)on'/ o '謝謝 – lzc

回答

2

使用eval EXPR

$match =~ /^(?:[=!][~=]|eq|ne)\z/ 
    or die("Unrecognized operator \"$match\"\n"); 

my $rv; 
eval("\$rv = \$value $match \$operand; 1") 
    or die [email protected]; 

使用調度表:

my %ops = (
    '=~' => sub { $_[0] =~ $_[1] }, 
    '!~' => sub { $_[0] !~ $_[1] }, 
    '==' => sub { $_[0] == $_[1] }, 
    '!=' => sub { $_[0] != $_[1] }, 
    'eq' => sub { $_[0] eq $_[1] }, 
    'ne' => sub { $_[0] ne $_[1] }, 
); 

my $op = $ops{$match} 
    or die("Unrecognized operator \"$match\"\n"); 

my $rv = $op->($value, $operand); 

我看不出封可以是任何用處。