У вас есть какая-то конкретная причина использовать такой запутанный разделитель?--
имеет известное значение для большинства пользователей сценариев, и это не так.
Если вам нужно прочитать опции со списками, Getopt::Long
имеет методы для работы с массивами ввода, возможно, что-то подобное может вам помочь;смотрите под «Опции с несколькими значениями» .Этот модуль входит в стандартный дистрибутив, поэтому вам даже не нужно ничего устанавливать.Я использую его для любого сценария, который требует более одного (может быть, двух) входных данных и определенно, если какие-либо входные данные являются необязательными.
См. Также здесь и даже больше здесь .
Вот краткий пример: если у вас есть возможность изменить синтаксис ввода, вы получите требуемую функциональность:
#!/usr/bin/env perl
# file: test.pl
use strict;
use warnings;
use Getopt::Long;
my @letters;
my @words;
GetOptions(
"letters=s{,}" => \@letters,
"words=s{,}" => \@words
);
print "Letters: " . join(", ", @letters) . "\n";
print "Words: " . join(", ", @words) . "\n";
Дает:
$ ./test.pl --letters a b c --words he she we
Letters: a, b, c
Words: he, she, we
Хотя я никогда не поощрял бы написание собственного парсера, я не мог понять, почему кто-то выбрал форму, которая у вас была, поэтому я буду действовать исходя из того, что вы не контролируете этот формат и вам нужно обойти его,Если это так (в противном случае рассмотрите более стандартный синтаксис и используйте приведенный выше пример), вот простой анализатор, который должен помочь вам начать работу.
NB. Причина, по которой вы НЕ пишете свои собственные, состоит в том, что другие хорошо проверены и имеют сглаженные случаи.Также знаете ли вы, что бы вы сделали с чем-то между --
и -title
?Я предположил, что, поскольку новый -title закончил бы предыдущий, вы могли бы иметь что-то среднее между ними и поместить их все по порядку в ключ «default».
#!/usr/bin/env perl
# file: test_as_asked.pl
# @ARGV = qw/default1 -letters a b c -- default2 -words he she we -- default3/;
use strict;
use warnings;
my %opts;
# catch options before a -title (into group called default)
my $current_group = 'default';
foreach my $opt (@ARGV) {
if ($opt =~ /\-\-/) {
# catch options between a -- and next -title
$current_group = 'default';
} elsif ($opt =~ /\-(.*)/) {
$current_group = $1;
} else {
push @{ $opts{$current_group} }, $opt;
}
}
foreach my $key (keys %opts) {
print "$key => " . join(", ", @{ $opts{$key} }) . "\n";
}
Дает:
$ ./test_as_asked.pl default1 -letters a b c -- default2 -words he she we -- default3
letters => a, b, c
default => default1, default2, default3
words => he, she, we