如何解析Clojure中的URL参数?

Chr*_*isR 19 clojure

如果我有请求,"size=3&mean=1&sd=3&type=pdf&distr=normal"那么编写(defn request->map [request] ...)接受此请求的函数并返回映射的惯用方法是什么{:size 3, :mean 1, :sd 3, :type pdf, :distr normal}

这是我的尝试(使用clojure.walk和clojure.string):

(defn request-to-map
   [request]
   (keywordize-keys
      (apply hash-map
             (split request #"(&|=)"))))
Run Code Online (Sandbox Code Playgroud)

我对其他人如何解决这个问题很感兴趣.

ord*_*rig 16

假设您要解析HTTP请求查询参数,为什么不使用ringring.middleware.params包含你想要的东西.

参数提取功能如下:

(defn- parse-params
  "Parse parameters from a string into a map."
  [^String param-string encoding]
  (reduce
    (fn [param-map encoded-param]
      (if-let [[_ key val] (re-matches #"([^=]+)=(.*)" encoded-param)]
        (assoc-param param-map
          (codec/url-decode key encoding)
          (codec/url-decode (or val "") encoding))
         param-map))
    {}
    (string/split param-string #"&")))
Run Code Online (Sandbox Code Playgroud)


Ken*_*llB 15

使用form-decodekeywordize-keys:

(use 'ring.util.codec)
(use 'clojure.walk)

(keywordize-keys (form-decode "hello=world&foo=bar"))

{:foo "bar", :hello "world"}
Run Code Online (Sandbox Code Playgroud)


Bri*_*per 10

您可以使用许多Java库轻松完成此操作.除非我仔细阅读URI规范并确保我没有遗漏任何边缘情况(例如,在查询中出现两次具有不同值的params),否则我会犹豫是否尝试滚动我自己的解析器.这使用jetty-util:

(import '[org.eclipse.jetty.util UrlEncoded MultiMap])

(defn parse-query-string [query]
  (let [params (MultiMap.)]
    (UrlEncoded/decodeTo query params "UTF-8")
    (into {} params)))

user> (parse-query-string "size=3&mean=1&sd=3&type=pdf&distr=normal")
{"sd" "3", "mean" "1", "distr" "normal", "type" "pdf", "size" "3"}
Run Code Online (Sandbox Code Playgroud)