【问题标题】:Pass regex into perl subroutine将正则表达式传递给 perl 子例程
【发布时间】:2013-12-17 23:45:51
【问题描述】:

情况

我正在创建一个简单的模板文件,该文件将有助于创建未来的脚本,以便通过 *nix 系统上的命令行执行各种任务。作为其中的一部分,我可能会要求用户输入需要根据源代码中提供的正则表达式进行验证的数据。

问题

当我尝试通过命令行运行 Perl 代码时,开始产生错误。我正在尝试将正则表达式传递到重复子例程中,但我不确定如何准确执行此操作。我知道我可以使用eval 执行字符串,但是由于惯例,这是我想避免的。

错误:

Use of uninitialized value $_ in pattern match (m//) at scripts/template line 40.
Use of uninitialized value $resp in concatenation (.) or string at scripts/template line 37.

代码:

#!/usr/bin/env perl

use strict;
use warnings;
use Cwd;
use Term::ANSIColor;
use Data::Dumper;

my $log = "template.log";
my $task = "template";
my $cwd = getcwd();
my $logPath = $cwd . "/". $log;

print ucfirst($task) . " utility starting...\n";
system("cd ~/Desktop");
system("touch " . $log);
&writeLog("Test");

sub writeLog {
    open(my $fh, '>>', $logPath) or die "Could not open file '$log' $!";
    print $fh $_[0] . localtime() . "\n";
    close $fh;
    return 1;
}

sub ask {
    my $question = $_[0];
    my $input = $_[1];
    my $resp = <>;
    chomp($resp);
}

sub repeat {
    my $pat = $_[0];
    my $resp = $_[1];
    print $pat . "\n";
    print $resp . "\n";
}

&repeat(/foo|bar/i, "y");

我尝试过的:

根据这些来源:


sub repeat {
    my $pat =~ $_[0];
    my $resp = $_[1];
    if($pat !~ $resp) {
        print "foo\n";
    } else {
        print "bar\n";
    }
}

感谢任何帮助!

【问题讨论】:

  • 这个&amp;repeat(/foo|bar/i, "y"); 没有传递正则表达式,这是传递$_ =~ /foo|bar/i 的结果。
  • 我还要注意,如果您允许用户输入正则表达式,您实际上是在说“请输入代码,我将执行它”。 qr/?{ system "rm -rf *" }/ 会带来不愉快的一天。

标签: regex perl function parameters subroutine


【解决方案1】:

要创建一个正则表达式供以后使用,我们使用 qr//:

my $regexp = qr/^Perl$/;

这会编译正则表达式以供以后使用。如果您的正则表达式有问题,您会立即听到。要使用这个预编译的正则表达式,您可以使用以下任何一种:

# See if we have a match
$string =~ $regexp;

# A simple substitution
$string =~ s/$regexp/Camel/;

# Comparing against $_
/$regexp/;

【讨论】:

    【解决方案2】:

    /.../ 这样的纯正则表达式文字与$_ 匹配。要创建独立的正则表达式对象,请使用qr// 引号:

    repeat(qr/foo|bar/i, "y");
    

    (请不要调用像 &amp;sub 这样的 subs,除非您知道何时以及为什么需要这样做。)

    【讨论】:

    • 何时以及为何需要?
    • @djthoms ikegami 有一个很好的overview of the &amp; in Perl 提到了这些案例(简而言之,&amp;sub 仅在禁用称为“原型”的特定功能时才需要,您甚至没有使用)。
    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    相关资源
    最近更新 更多