问题描述
是否有一种很好的(理想的CPAN)方式来使用Perl处理任意命令行选项?
Is there a good (ideally CPAN) way to process arbitrary command line options with Perl?
例如,使用字符串-a 1 -b'z -x'-c -d 3 4
并生成 GetOpt :: Long
-像数据结构一样:
E.g., take a string "-a 1 -b 'z -x' -c -d 3 4"
and generate a GetOpt::Long
- like data structure:
{ a=>1, b=>"z -x", c=>1, d=>[3,4] } # d=>"3 4" is acceptable
要注意的是,
-
这套选项事先未知;因此我们似乎无法原样使用
GetOpt :: Long
。
值本身可以包含其他选项,因此只需解析#\b +-(\S +)\b#
模式的字符串以查找该字符串中的所有选项,似乎也不是有些参数可能是= s类型,某些参数是= s @,某些参数是 -xabc类型。
The values themselves can contain other options, so simply parsing the string for #\b+-(\S+)\b#
pattern to find all the options in THAT string also seems to not be possible, and further complicated that some parameters are of =s type, some =s@, some of "-x a b c" type.
此外,即使我们可以做#2, GetOptionsFromString
是否支持尊重引用值的正确标记化?
Moreover, even if we could do #2, does GetOptionsFromString
support correct tokenizing that respects quoted values?
注意:为了便于练习,假设所有参数都是选项,也就是说,如果将字符串分成(可能带引号的)标记,您的结构始终是
NOTE: Assume for the purpose of exercise that ALL arguments are "options", in other words, if you split up the string into (possibly-quoted) tokens, your structure is always
"-opt1 arg1a [arg1b] -opt2 ....".
换句话说,任何以破折号开头的单词/令牌都是一个新选项,所有随后的不以破折号开头的单词/标记就是该选项的值。
In other words, any word/token that starts with a dash is a new option, and all the subsequent words/tokens that do NOT start with a dash are values for that option.
推荐答案
使用Text :: Parsewords的快速示例
A quick example using Text::Parsewords and a simple state machine.
#!/usr/bin/env perl
use strict;
use warnings;
use Text::ParseWords qw/shellwords/;
my $str = q{-a 1 -b 'z -x' -c -d 3 4};
my $data = parse($str);
use Data::Printer;
p $data;
sub parse {
my $str = shift;
my @tokens = shellwords $str;
my %data;
my @keys;
my $key = '_unknown';
foreach my $token (@tokens) {
if ($token =~ s/^\-//) {
$key = $token;
push @keys, $key;
next;
}
if ( ref $data{$key} ) {
push @{ $data{$key} }, $token;
} elsif (defined $data{$key}) {
$data{$key} = [ $data{$key}, $token ];
} else {
$data{$key} = $token;
}
}
foreach my $key (@keys) {
next if defined $data{$key};
$data{$key} = 1;
}
return \%data;
}
这篇关于是否有CPAN方法来解析随机命令行选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!