Perl如何将正则表达式传递给我的子程序,如grep

时间:2014-06-30 12:46:23

标签: regex perl parameters grep

print grep /test/, "mytestphrase";

使用grep语法,您可以传入一个没有引号的正则表达式。 我希望我的子程序具有相同的行为,如下所示:

use strict; 
use warnings;

sub testsub {
    my $regex = shift;
    my $phrase = shift;

    print grep $regex, $phrase;
}

testsub /test/, "mytestphrase";

然而,它在testsub调用之前尝试对我的正则表达式进行评估$_,发出以下错误:

Use of uninitialized value $_ in pattern match (m//) at ./a.pl line 14.

是否可以像grep命令一样调用testsub以及如何修改子例程以支持它?

3 个答案:

答案 0 :(得分:4)

传递如下参数:

testsub qr/test/, "mytestphrase";

还将$regex的使用率更改为/$regex/

#!/usr/bin/perl

use strict; 
use warnings;

sub testsub {
    my $regex = shift;
    my $phrase = shift;
    print grep /$regex/, $phrase;
}

testsub qr/test/, "mytestphrase";

答案 1 :(得分:2)

AFAIK没有办法复制grep的特殊“拿一个块或采取一个裸表达式”的语法。 As pointed out in TLP's answer,您可以使用&@原型获取foo {...} LIST语法,但不能要求块或标量。

也没有原型来获得简单的正则表达式。您必须传入已编译的正则表达式qr/.../as noted by M42

原型不完整。它们无法表达Perl内置函数的全部功能。 opensplitprint,甚至是chomp等显然简单的print prototype 'CORE::some_function'。您可以通过询问&@来查看此内容。有人说这是原型的弱点。有人说这是Perl内置功能的疯狂。

只有在替换内置函数时才应使用原型。他们真的是最好的避免。少数有效成语之一是使用foo {...} LIST原型为列表处理提供qr//成语。

我建议您将sub { ... }grep正常传递给您的函数并将其传递给qr//

我是否说无法这样做?我在想什么,这是Perl!如果你真的真的想要这个功能,你可以深入研究Devel::Declare。此模块允许您提供自己的函数调用语法。说它不容易使用是轻描淡写。 Method::SignaturesTryCatch之类的东西用它来发挥他们的魔力。如果您只是在计算{{1}},我建议不要将Devel :: Declare放入生产代码中。尽管如此,还是把它搞乱了。

答案 2 :(得分:1)

如果你阅读http://perldoc.perl.org/perlsub.html#Prototypes,你会发现这个例子:

Declared as          Called as
...
sub mygrep (&@)      mygrep { /foo/ } $a, $b, $c

你可能指的是什么。

大多数情况下,原型并不是您想要的,不应该使用。原型用于使Perl子例程像某些内置函数一样工作,例如grep

至于建议,我建议你按照his answer中的M42建议做。