I have a problem with re-find in clojure. Actually I'm doing
(re-find #"-(?<foo>\d+)-(?<bar>\d+)-(?<toto>\d+)-\w{1,4}$"
"http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu" )
My result is fine:
["-9-31289-824-gt" "9" "31289" "824"]
But I would prefer to have a hash looking like:
{:foo "9" :bar "31289" :toto "824"}
I have understood that java.util.regex.Matcher/group is doing something like that but I haven't been able to use it correctly. Thanks for your help
The java regex library Clojure is built against (Java 1.6) doesn't support regex named capturing groups.
However, you can use Clojure's zipmap
function to combine name keys and re-find
's captured groups into a map. Groups that aren't matched will get a nil
value for the name key.
(zipmap [:foo :bar :toto]
(rest (re-find #"-(\d+)-(\d+)-(\d+)-\w{1,4}$"
"http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu")))
=> {:foo "9" :bar "31289" :toto "824"}
JDK didn't support named capture groups until JDK 7.
Here's announcement on oracle blog
Quote:
This convenient feature has been missed in Java RegEx for years, now it finally got itself in JDK7 b50.
Since clojure supports JDK >= 6 you're out of luck if you're looking for something native (clojure uses java regex Patterns and Matchers behind the scenes).
You can always use external libraries, like named-re. That one gives you exactly what you need.
Calling
(require 'named-re.core)
(re-find #"-(?<foo>\d+)-(?<bar>\d+)-(?<toto>\d+)-\w{1,4}$"
"http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu" )
will return
{:toto "824", :bar "31289", :foo "9", :0 "-9-31289-824-gu"}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With