I want to have a command for a plugin that has the following form:
add <quantity> <spell name> [additional options] where additional options is a space-separated list of command-line style switches that may be specified.
For example, valid input would be "add 10 magic missile", or "add 10 magic missile -d someStringWhichMayHaveSpaces -s someOtherString". Is there a nice way of doing this using regex when the switches can come in any order, and may not even be present? Valid switches are -d, -p, -s, -v, -w.
You suggest iterating over each word of the string?
Another idea i had was to have n regular expressions where n is the number of switches i support, something like "^.+ -d (.+)$" to pick out the argument for -d. The problem is that I need it to capture everything after -d, but stop just before encountering any of the other switches (e.g, "-w").
Zero or more spaces after the digits (we already have a space after "add")
The spell name is anything except a hyphen - however at least one thing - stored in capture "spell"
The arguments are everything after the spell name (if anything), stored in capture "args"
The pattern for the arguments (in Lua regexp) is:
A hyphen
A letter
One or more of anything except a hyphen
Test string:
add 10 magic missile -d some String Which May Have Spaces -s someOtherString
Output:
quantity = 10
spell = magic missile
args = -d some String Which May Have Spaces -s someOtherString
Got argument d
Got value some String Which May Have Spaces
Got argument s
Got value someOtherString
Test:
add magic missile
Output:
quantity = nil
spell = magic missile
args =
You can test for quantity == nil to see if quantity was supplied or not.
<aliases>
<alias
match="^add (?P<quantity>\d*) *(?P<spell>[^-]+)(?P<args>.*)$"
enabled="y"
regexp="y"
send_to="12"
sequence="100"
>
<send>
quantity = tonumber ("%<quantity>")
print ("quantity = ", quantity)
spell = Trim ("%<spell>")
print ("spell = ", spell)
args = "%<args>"
print ("args = ", args)
while true do
-- find first argument
st, en, arg = string.find (args, "%-(%a+)")
-- see if any found
if not st then
break -- all done!
end -- if
-- find next argument, if any
st2 = string.find (args, " %-", en)
if not st2 then
st2 = -1
end -- if not found
value = Trim (args:sub (en + 1, st2))
print ("Got argument", arg)
print ("Got value", value)
args = args:sub (st2) -- remove this argument
end -- while
</send>
</alias>
</aliases>
For advice on how to copy the above, and paste it into MUSHclient, please see Pasting XML.
Test:
add 10 magic missile -d some String Which May Have Spaces -s some-Other-String -foo bar
Output:
quantity = 10
spell = magic missile
args = -d some String Which May Have Spaces -s some-Other-String -foo bar
Got argument d
Got value some String Which May Have Spaces
Got argument s
Got value some-Other-String
Got argument foo
Got value bar
I've made it this time so you can have a longer word (eg. "-foo") as the parameter name. Of course, then you have to have a space after it to delimit it from what the argument is.