input: spam eggs "spam and eggs" output: @["spam", "eggs", "spam and eggs"]
I want to support both single and double quotes, and I'm having trouble wrapping my brain around how to do this. I've been thinking maybe splitting with a regular expression is the way to go, but I wondered if there is a simpler way (perhaps already in the standard library that I've missed).
Try this
import strutils
var str = "spam eggs \"spam and eggs\" asd zxc"
var spl = str.split("\"")
for s in 0..spl.high:
if spl[s].startsWith(" ") or spl[s].endsWith(" "):
spl[s] = spl[s].strip
echo spl
Assuming that that input is from the command line, you can use the inbuilt commandLineParams() instead of manually parsing it (example in my notes: https://scripter.co/notes/nim/#command-line-parameters).
Though, I use the cligen package from Nimble for my CLI parsing needs in general for much more CLI arg and switch parsing and auto doc support.
Thanks! I came up with the following:
import parseutils, strutils
proc splitArgs(args: string): seq[string] =
var
parsed, tmp: string
i, quotes: int
while i < args.len:
i += args.parseUntil(parsed, Whitespace, i) + 1
tmp.add(parsed)
if parsed.startsWith('"'):
quotes.inc
if parsed.endsWith('"'):
quotes.dec
elif quotes > 0:
tmp.add(" ")
if quotes == 0:
tmp.removePrefix('"')
tmp.removeSuffix('"')
result.add(tmp)
tmp = ""
if tmp.len > 0:
result.add(tmp[1 .. ^2])
let text = "spam eggs \"spam and eggs\""
doAssert text.splitArgs == @["spam", "eggs", "spam and eggs"]
I chose not to cover single quotes because I don't want to have to handle words like "don't". Advice on how I could improve on this?
Regex....
(w*b)*?|(?<=").*(?=")$