Ben Webb
Ben Webb

Reputation: 27

Clojure/Java.regex: Why does re-find throw cast exceptions for my parenthesised regex (below) but not for a simple expression like "\d+"?

Hi I'm new to Clojure and not very experienced with java and I'm struggling to use a more complex RegEx with the below code:

(defn clean-input [s]
  (read-string (re-find #"\d+" s)))
(defn map-numbers [s]
  (map clean-input (clojure.string/split s #" ")))

(map-numbers "1 2 3/3 4 5")
;=> (1 2 3 4 5)

I would like to take a delimited string like the one below and remove any non-numerics and map the remaining numbers into a lazy sequence, So I can square each item in the sequence and output the result in another function.

"1 2 3.2 4/4 ff 32.12342e+12 red 1.79769313486231570e+308d 0.001 32/3 0xe22A23 9C5.FF3B645A1C16 0556 0xff 0XFF 0x1f 0x223323223 hg 76 ghg6667  2r1111  32r34a32 33r35545 123."

So I have constructed the below (slightly ugly) RegEx do this and it seems correct using regexr.com I've made this multiline and added comments for readability but is a single line when used in the code.

 (\d+\.\d+(e(-|\+)\d+)?)                             ;floats and scientific notation
|(\d+\/\d+)                                          ;fractions
|(0(x|X)([A-Fa-f]|\d)+)                              ;hex
|(([2-9]|[1-2][0-9]|3[0-2])(r|R)(([A-Za-z]|\d)+))    ;radix(ish) 
|(\d+)                                               ;int and oct

When I replace "\d+" with the above RegEx I get the following casting exceptions:

Error printing return value (ClassCastException) at clojure.core/read-string (core.clj:3805). class clojure.lang.Cons cannot be cast to class java.lang.String (clojure.lang.Cons is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')

I've tried to read into the issue further but I haven't made any headway, would someone be kind enough to explain what I'm doing wrong and what I should be doing instead? It would be much appreciated, Thanks

Upvotes: 1

Views: 135

Answers (1)

amalloy
amalloy

Reputation: 92067

(read-string (re-seq re x)) makes little sense. re-seq returns a sequence, and read-string reads a string. These don't match, so the error you get is expected, no matter what re and x are.

The surprise is that you claim your first example works. It obviously shouldn't, and when I copy it into a new repl I find that indeed it does not work. Please make sure you include actual failing code when asking for help with it. If you edit it to make sure it's minimal (a good idea!), make sure the error is still reproducible after your edit.

Upvotes: 2

Related Questions