2

我让下面的代码可以根据需要工作,但想知道是否有更好的方法可以不带引号。

myScript.pl --filter 'key1 foo bar' --filter 'key2 baz qux'

#!/usr/local/bin/perl5.8.8
use warnings;
use strict;
use Getopt::Long;
use Data::Dumper;

my %filter;

GetOptions("filter=s" => sub { my @args = split(/\s/, $_[1]); $filter{$args[0]}{value1} = $args[1]; $filter{$args[0]}{value2} = $args[2]; });

print Dumper %filter;

我得到了令人满意的输出:

$VAR1 = 'key2';
$VAR2 = {
          'value1' => 'baz',
          'value2' => 'qux'
        };
$VAR3 = 'key1';
$VAR4 = {
          'value1' => 'foo',
          'value2' => 'bar'
        };

但是,我想像这样使用它,不带引号:

myScript.pl --filter key1 foo bar --filter key2 baz qux --other_option ...

key1 和 key2 在这里是哈希键,并且是唯一的。

有什么想法/建议吗?

4

2 回答 2

4

当我上次检查时(几年前),CPAN 上列出的 20-30 个Getopt模块中没有一个可以处理您所展示的一串参数,而且我所知道的大多数基于 C 的参数解析代码都不能处理那个任何一个。(我确实有一个处理它的 C 代码解析器,前提是您知道要使用多少个参数。目前尚不清楚您是否需要 1 个键和 2 个值,或者值列表是否可以比这更多变量。)


可能是我看的不够仔细。

Getopt::Long有以下选项:

警告:以下是实验性功能。

选项可以一次取多个值,例如

--coordinates 52.2 16.4 --rgbcolor 255 255 149

这可以通过在选项规范中添加重复说明符来实现。重复说明符与可与正则表达式模式一起使用的 {...} 重复说明符非常相似。例如,上面的命令行将按如下方式处理:

GetOptions('coordinates=f{2}' => \@coor, 'rgbcolor=i{3}' => \@color);

选项的目标必须是数组或数组引用。

还可以指定选项采用的最小和最大参数数量。foo=s{2,4}表示一个选项,该选项至少需要两个且最多 4 个参数。foo=s{,}表示一个或多个值;foo:s{,}表示零个或多个选项值。

这将生成一个包含键和两个值的数组。鉴于这需要与拥有多个条目(每个条目一个--filter)的能力相结合,您可能仍然不走运,但您应该Getopt::Long非常仔细地探索。

于 2011-11-26T06:13:14.073 回答
3

您可以使用选项名称为非选项参数指定回调<>并适当调整您的%filters哈希,如下所示:

GetOptions('filter=s' =>  \&set_filter, '<>' => \&non_option);

我想你的@ARGV 最终会是空的,除非你使用 a--虽然。

于 2011-11-26T06:30:45.437 回答