繁体   English   中英

Perl对grep {//}和eval {grep //}语法的混淆

[英]Perl confusion over grep {//} and eval {grep //} syntax

请介绍一下这两种grepPerl中 ping的方式,以及它们彼此之间的区别

eval {grep /pattern/, ....};

和正常的,

grep {/pattern/} ....

首先,您的备选方案之间存在2个独立差异,它们具有不同的用途。 eval包装grep允许您捕获通常致命的错误(如正则表达式中的语法错误)。 grep关键字后面放置一个块,可以使用比单个表达式更复杂的匹配规则。

以下是您可以从2个示例中进行的4种组合:

@y = grep /pattern/, @x;             # grep EXPR, no eval
@y = grep { /pattern/ } @x;          # grep BLOCK, no eval
eval { @y = grep /pattern/, @x };    # grep EXPR inside eval BLOCK
eval { @y = grep { /pattern/ } @x }; # grep BLOCK inside eval BLOCK

现在我们可以从两个不同的问题中查看更多细节:您从eval获得了什么,以及使用grep BLOCK语法获得了什么? 在上面显示的简单情况中,你从任何一个中获得任何东西。

当你想要做grep其中,匹配条件比一个简单的正则表达式更复杂, grep BLOCK为您提供了如何表达的条件更大的灵活性。 您可以在块中放置多个语句并使用临时变量。 例如grep中的这个grep:

# Note: not the most efficient method for finding an intersection of arrays.
my @a = qw/A E I O U/;
my @b = qw/A B D O P Q R/;
my @intersection = grep { my $x = $_; grep { $_ eq $x } @b } @a;
print "@intersection\n";

在上面的例子中,我们需要一个临时的$x来保存外部grep测试的值,因此它可以与内部grep中的$_进行比较。 内部grep可以在没有BLOCK的情况下编写为grep $_ eq $x, @b但我认为使用相同的语法看起来更好看。

如果您正在查找在运行时确定的正则表达式的匹配项,并且您不希望程序在正则表达式无效时中止,则eval块将非常有用。 例如:

@x = qw/foo bar baz quux xyzzy/;
do {
  print STDERR 'Enter pattern: ';
  $pat = <STDIN>;
  chomp $pat;
  eval {
    @y = grep /$pat/, @x;
  };
} while($@);
print "result: @y\n";

我们向用户询问模式并打印来自@x的匹配列表。 如果模式不是有效的正则表达式,则eval捕获错误并将其放入$@ ,程序继续运行(打印“无效”消息并继续循环,以便用户可以再次尝试。)当有效的正则表达式时输入后,没有错误,所以$@为false,打印“结果”行。 样品运行:

Enter pattern: z$
result: baz
Enter pattern: ^(?!....)
result: foo bar baz
Enter pattern: ([^z])\1
result: foo quux
Enter pattern: [xyz
Invalid pattern
Enter pattern: [xyz]
result: baz quux xyzzy
Enter pattern: ^C

请注意, eval不会捕获固定正则表达式中的语法错误。 这些是在编译脚本时编译的,所以如果你有一个像这样的简单脚本

perl -ne 'print if eval { /[xyz/ } or eval { /^ba/ }'

它立即失败了。 eval没有帮助。 相比于

perl -ne '$x = "[xyz"; $y = "^ba"; print if eval { /$x/ } or eval { /$y/ }'

这是相同的事情,但使用从变量构建的正则表达式 - 这个运行并打印/^ba/匹配。 第一个eval总是返回false(设置$@ ,如果你不看它就没关系)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM