这个正则表达式在这里做什么

时间:2013-07-30 15:33:54

标签: perl

for $file ( $ftp -> ls() )
    {
        $bar = file;                

        $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
        $dst_pattern =~ s/\$\&/\$bar/g;

        $dst_dir1 = eval( $dst_dir );
        $dst_file = eval( $dst_pattern ); 
    }

在Perl中,对文件名$bar做了什么。所以$bar正在取代\$\&,但这是什么?还会在字符串上评估什么

3 个答案:

答案 0 :(得分:3)

看起来它取代了'$&'的每一次出现在$foo中使用'$ bar'。这是在数据中实现简单占位符令牌语法的典型方法。

eval返回的值是将$foo的值视为Perl源代码的结果。假设正常执行,eval将返回$foo中评估的最后一个表达式(如果执行了一个return语句的参数)。请注意,评估$foo也可能有副作用(I / O,变量赋值等)。如果不知道$foo中的内容是什么,就不可能多说。

答案 1 :(得分:0)

很难给出全面的答案,因为我们不知道嵌入代码段的代码的优越目标。特别是关于$foo$bar中的内容。

尽管如此,我还是编写了一个小脚本来说明具体的替换和以下eval语句:

#!/usr/bin/env perl 

$bar = "10";
$foo = '10*$&';

print 'content of `$bar`: ', $bar, "\n";
print 'content of `$foo` befor substitution: "', $foo, "\"\n";

$foo =~ s/\$\&/\$bar/g;

print 'content of `$foo` after substitution: "', $foo, "\"\n";

$a = eval($foo);

print 'result of the evaluation: ', $a, "\n";

脚本的输出是:

content of `$bar`: 10
content of `$foo` befor substitution: "10*$&"
content of `$foo` after substitution: "10*$bar"
result of the evaluation: 100

结束eval语句评估$foo的内容,即"10*$bar",就像它是一个常规的perl表达式一样。因此,你可以想到这一行

$a = eval($foo);

作为

$a = 10*$bar;

因此,值100存储在$a

答案 2 :(得分:0)

我注意到了一件事......

for $file ( $ftp -> ls() )
{
    $bar = file;

这应该是$bar = $file而不是$bar = file(您的脚本在$中缺少前导file)。否则,您只需将字符串file放入$bar即可。

表达的另一部分是:

$dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
$dst_pattern =~ s/\$\&/\$bar/g;

$dst_dir$dst_pattern的价值是多少?这就是 真正的 问题。

某处正在设置$dst_dir$dst_pattern。这是您将FTP中的文件替换为这些字符串的位置。然后我注意到了这一点:

$dst_dir1 = eval( $dst_dir );
$dst_file = eval( $dst_pattern ); 

$dst_dir$dst_file似乎是某种命令?为什么还要使用eval?这两个字符串的值是什么?为什么要通过eval运行它们?

发生了什么事情,这两个命令中包含字符串$&,并且您正在替换您正在使用该字符串的文件。

我们假设$dst_dir等于$ftp->get("$&")。您从$ftp->ls命令获取的文件名(假设它是bar.txt被替换为该字符串。因此,$dst_dir1设置为$ftp->get("bar.txt");

看着整个循环:

for $file ( $ftp -> ls() )
{
    $bar = file;                

    $dst_dir     =~ s/\$\&/\$bar/g;     #so this is replacing \$\& with $src
    $dst_pattern =~ s/\$\&/\$bar/g;

    $dst_dir1 = eval( $dst_dir );
    $dst_file = eval( $dst_pattern ); 
}

我看到另一个问题。您正在循环浏览每个文件,并且每次都替换$&$dst_dir中的$dst_pattern。但是,如果您为每个文件执行此操作,并且未重置$dst_dir$dst_pattern的原始值。这意味着第二次进行循环时,您不会更改$dst_dir$dst_pattern。而且,所有其他时间你也会经历你的循环。

您也没有检查以确保替换实际有效,并且您没有通过检查eval的值来检查$@是否有效。

最重要的是,您没有设置use strict;,可能不会设置use warnings;

这是循环的新版本:

for my $file ( $ftp->ls ) {
    my $dist_dir     = $dst_dir;      # Make sure you don't futz with your
    my $dist_pattern = $dst_pattern;  # original templates!

    # Check to make sure replacements work!
    if ( not $dist_dir =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_dir");
    }
    if ( not $dist_pattern =~ s/\$\&/\$file/g ) {
       die qq(Couldn't put file name "$file" into "$dist_pattern");
    }

    # Check for Eval!
    my $dst_dir1;
    my $dst_file1;
    $dst_dir1 = eval( $dist_dir );
    if ( "$@" ) {
       die qq(Evaluation of `$dist_dir` failed!: $@ );
    }

    $dst_file1 = eval( $dist_pattern );
    if ( "$@" ) {
      die qq(Evaluation of '$dist_pattern' failed!: $@);
    }
}

这是为了确保替换有效,并且每次都保存不修改模板。