Parse a single-line string into a structured set of sub-strings representing positional arguments, named arguments and flags.
Supports:
- configurable separators (e.g. space, comma)
- configurable assignment operators (e.g.
=,:) - quoted / enclosed tokens (e.g.
"a b",{a, b}) - escaping (e.g.
"a \" b") - duplicate named argument handling (e.g.
a=1 a=2 a=3)
parser = Argstring::Parser.new
result = parser.parse('arg1 foo=bar "a b"=c')
result.valid? # => true
result.position[1].text # => "arg1"
result.name["foo"].text # => "bar"
result.name["a b"].text # => "c"Note that no type coercion takes place, so a=1 is a named argument a with the string value "1". If you want to interpret values as other types you can handle that in your own further processing step.
Argstring recognizes three kinds of arguments:
arg1 arg2 arg3
Each positional argument:
- is indexed starting at 1
- is available via
result.position[index] - is also optionally treated as a flag (see below)
Example:
result.position[1].text # => "arg1"key=value
keyandvalueare always strings- assignment operators are configurable
- exactly one assignment operator per argument is allowed
Example:
foo=bar
"a b"="c d"Access via:
result.name["foo"].textBy default, every positional argument is also treated as a flag:
verbose
Equivalent to:
{ "verbose" => true }Access via:
result.flag["verbose"] # => trueFlags can be disabled via configuration.
You can override the default configuration to modify how the arg string is parsed:
parser = Argstring::Parser.new(
separator: /\s/,
escape: "\\",
assignment: ["="],
enclosers: [{open: '"', close: '"' }, {open: "'", close: "'"}],
duplicates: :last,
flags: true,
positional: true
)separator
: Defines how arguments are split. /\s/ splits on whitespace (collapsed). A non-whitespace character (e.g. ",") splits only on that character, allows empty arguments, ignores surrounding whitespace, and permits spaces inside arguments.
assignment
: Array of characters that are used to assign a named argument. Set to the empty array to disable named arguments.
escape
: Specify the single character that is the escape character. Set to the empty string to disable escaping.
enclosers
: Array of hashes each with keys open and close, providing the characters that can be used to enclose (quote) part of the string, forcing it to be treated as a single token.
duplicates: :last or :first
: Controls which value is effective as Argument#value when a named argument appears multiple times. All values are preserved in Argument#values.
flags
: When enabled, positional arguments also emit boolean flags using their value as the flag name.
positional
: Controls whether positional arguments are recorded and indexed.
Parser#parse returns an Argstring::Arguments instance.
result.valid? # boolean
result.errors # array of error messages
result.all # all Argument objects in encounter orderresult.positional # positional Argument objects
result.named # named Argument objects
result.flags # flag Argument objectsresult.position[1] # => Value of first positional argument
result.name["foo"] # => Value of named 'foo' argument
result.flag["bar"] # => true if flag was setEach argument is represented by an Argument instance:
arg.kind # :positional | :named | :flag
arg.position # integer (positional only)
arg.name # Name token (named/flag only)
arg.value # Value token
arg.values # array of Value tokensName and Value tokens expose:
token.text # the parsed string value
token.raw # the part of the original arg string that was parsed
token.enclosed? # was this token enclosed (e.g. in quotes)
token.enclosure # { open: "..", close: ".."} or nil: details of the enclosure if it was enclosedEnclosures allow tokens to contain separators, whitespace, or assignment operators.
Default enclosers:
"double quotes"
'single quotes'Examples:
"a b"
key="c d"
'a=b'
'contains "double quotes" here'
Note that an unterminated enclosure will cause a parsing failure.
Default escape character:
escape: "\\" # a single backslashYou can escape enclosure markers, assignment operators and the escape character itself. You can't escape whitespace if it's used as the argument separator.
Examples:
a\=b # => positional "a=b" rather than named
"a \"quote\"" # => value: a "quote"
The separator determines how arguments are split. Only separators create new arguments.
separator: /\s/- Any whitespace splits arguments
- Runs of whitespace are collapsed
- Whitespace cannot appear inside tokens unless enclosed
Examples:
a b c # => 3 positional arguments
a=b c=d # => 2 named arguments
a b=c # => positional "a", named "b"
Important behaviors:
a = b # => positional "a", positional "=", positional "b"
"a b"=c # => named "a b"
"a b = c" # => a single positional argument with the value "a b = c"
separator: ","- Arguments are split only on the separator character
- Whitespace around segments is ignored
- Whitespace around assignment operators is ignored
- Whitespace inside segments is preserved
Examples:
a,b,c # => 3 positional
a, b , c # => same
a=b,c=d # => 2 named
a = b , c = d # => same as above
By default:
assignment: ["="]You may supply multiple operators:
assignment: ["=", ":"]Rules:
- At most one assignment operator per argument
- Assignment operators inside enclosures are ignored
- Assignment operators can be escaped
Controlled via:
duplicates: :last # defaultOptions:
:last: last value wins:first: first value wins
Regardless of mode:
- all values are preserved in
Argument#values Argument#valueis the effective value
Example:
a=1 a=2 a=3
arg = result.named.first
arg.value.text # => "3" (with :last)
arg.values.map(&:text) # => ["3", "2", "1"]