Fork me on GitHub
#beginners
<
2017-03-06
>
gamecubate21:03:13

Hi all. Trying to get from

”a b (c d)”
to
[:a :b [:c :d]]
...

gamecubate21:03:47

(->> (clojure.string/split “a b (c d)” #” “) (map keyword))
only gets me this far of course.

shan21:03:46

could try clojure.walk/keywordize-keys

shan21:03:22

actually nevermind, that's not a map

gamecubate21:03:50

(map keyword [”a” “b” “c” “d”])
works, of course.

gamecubate21:03:31

But it’s the parsing of string such that bracketed terms are returned as (sub) vectors of results that stumps me.

seancorfield21:03:04

Look at instaparse as a relatively easy way to go from strings to data structures. Assuming you know the grammar of the string.

gamecubate21:03:08

e.g.

“a (b c)" -> [a [b c]]

gamecubate21:03:00

Yes my grammar actually. Thanks will look it up.

gamecubate21:03:07

@seancorfield thanks

gamecubate21:03:33

@seancorfield Not light reading but I’m pretty sure this will do it. Thanks again.

aengelberg21:03:21

@gamecubate do you want nested parens to give you nested lists? e.g. a (b (c d))

gamecubate21:03:59

Actually, want to parse a string for nested parens, turning it into nested sequence

gamecubate21:03:43

(def my-string “a b (c d)”)

gamecubate21:03:42

Wanted:

[:a :b [:c :d]]
or
'(:a :b (:c :d))

vinai22:03:30

@gamecubate Interesting little problem. My attempt looks like this:

(def my-string "a b (c d)")

((fn to-keywords [a] (if (coll? a) (map to-keywords a) (keyword a)))
       (read-string (str "[" my-string "]")))

vinai22:03:24

I had to surround the string with [ and ] or some other thing to make it a data structure, and then the reader works okay.

vinai22:03:41

(:a :b (:c :d))

seancorfield23:03:50

FYI, read-string isn’t safe to use on arbitrary input since it can execute code. Consider clojure.edn/read-string instead.