Best way to write this in Elm? (Parser vs Regex)

Hey all,

So in my Javascript codebase I have a Regex that’ll take a string that’s essentially a bash command and split it into an array on spaces. However, it will keep all items between single quotes together in a single array index.

I was planning on using the same regex and use Regex.find until I stumbled onto Parsers.

It seems like a Parser might be a good way forward but then again I do have a regex that works pretty well (for now).

What would the idiomatic Elm way for this be? I feel like Parser might be my best best, but wanted to ask here before spending a ton of time learning that new concept on top of everything else.

P.S. I’m just messing around to see if I can take some of our more complex pieces of logic and move that into Elm for a potential rewrite we’ve been planning for the last year.


I like writing parsers, so I wrote up a very rough thing. I did not put it through a compiler or anything, so ask someone else if there are errors or anything. This is just for example!

notSingleQuote : Char -> Bool
notSingleQuote char =
  char /= '\''

unquotedStuff : Parser (List String)
unquotedStuff =
  keep oneOrMore notSingleQuote
    |> map (String.split " ")

quotedStuff : Parser (List String)
quotedStuff =
  succeed (\str -> [str])
  	|. symbol "'"
  	|= keep zeroOrMore notSingleQuote
  	|. symbol "'"

stuff : Parser (List String)
stuff =
  repeat zeroOrMore (oneOf [ quotedStuff, unquotedStuff ])
    |> map List.concat

You’d have to mess with it if tokens may contain a ' character (i.e. if a ' only counts if it directly follows a space)

Anyway, hope that gives some idea of how it’d look!

1 Like

That’s actually really helpful!

I was having trouble wrapping my head around all the types with parsers and
how they worked together, but that’s just fantastic!

Thanks so much for that. We don’t have any escaping at the moment, so this
is pretty much dead on for our current functionality it looks like.

I’ll definitely have to start playing around with this. :slight_smile: