in reply to Parsing a command-line string into an array

You could split on whitespace if none the values are expected to contain whitespace.

But let's say you want to pass -x 123 -y 'some val'.

One approach you could take is

prog [options] -X '-x 123' -X '-y some val' [options] [args]

Split on the first instance of whitespace only.

# my @extra_args = ( '-x', '123', '-y', 'some val' ); my @extra_args = map { split( /\s+/, $_, 2 ) } @opt_X;

Replies are listed 'Best First'.
Re^2: Parsing a command-line string into an array
by bliako (Abbot) on Dec 22, 2023 at 12:57 UTC

    hmmm, thanks but that opens a different can of worms. I would prefer to rely on a module than string-splitting.

    Perhaps I can do something like this way-round-about way:

    use Data::Roundtrip qw/json2perl/; use File::Temp; use strict; use warnings; my $cmdlinestr = <<EOC; -x 123 -y 'some val' EOC my ($fh, $fn) = File::Temp::tempfile(); print $fh 'use Data::Roundtrip qw/perl2json/; print perl2json(\@ARGV)' +; close $fh; my $ret = `$^X ${fn} ${cmdlinestr}`; my $args = json2perl($ret); print join("\n", @$args)."\n";

    Basically, rely on shell/perl to split the string into @ARGV, by spawning a basic perl script with the cmdline, get a json back and have that back to perl array. A lot can go wrong in this as well.

      I would prefer to rely on a module than string-splitting.

      We don't need a module to parse the grammar I suggested. The grammar is just that simple. That's the point.

      All we're doing is parsing the provided value to separate it into a name and a value. And we know the names can't contains spaces or punctuation (except perhaps _ or -).

      This is the same approach curl uses.

      curl ... -H 'Header1: ...' -H 'Header2: ...' ...

      You could leave out the initial dash if you want (-X 'y'/-X 'y ...').

      You could use equal signs instead of spaces if you want (-X 'y'/-X 'y=...').

      Whatever. The specifics aren't important and are quite flexible since all you have to do is separate a name (with a very limited set of characters) from the rest.

      The solution I presented does not "open a different can of worms". It in fact avoids doing so.