在Clojure中以功能方式重写此修剪功能

Seg*_*ult 2 string reduce clojure

我有这个功能(这个程序的摘录),我想以更吸引人/功能/惯用的方式重写.
它应该从s表达式中删除任何不必要的空格.

(defn trim 
  " Trim whitespace from code:
        (trim (trim \" d ' (    print   (   +   1   1 )  )\")
    ==> d '(print (+ 1 1))
    The replaced string is passed repeatedly to every call.
    Functional version
"
  [string] 
  (clojure.string/replace
   (clojure.string/replace
    (clojure.string/replace
     (clojure.string/replace
      (clojure.string/replace
       (clojure.string/replace
        (clojure.string/replace
         (clojure.string/replace
          (clojure.string/replace
           (clojure.string/replace
            string #"([^\\(\[{@~`'])(\(|\[|\{)" "$1 $2")
           #"(\)|\]|})(\[|\(|\{)" "$1 $2")
          #"[ \t]*(\)|\]|\})" "$1")
         #"[ \t]{2,}" " ")
        #"(\)|\]|\})[ \t]*(?=(\)|\]|\}))" "$1")
       #"(\(|\[|\{)[ \t]*(?=(\(|\[|\{))" "$1")
      #"^[ \t]*" "")
     #"(\\\{|\\\(|\\\[) " "$1  ")
    #"(\{|\(|\[) " "$1")
   #" ('|`) (\(|\[|\{)" " $1$2"))
Run Code Online (Sandbox Code Playgroud)

我对它现在看起来的样子不是很满意,因为很难弄清楚它是如何工作的(乍一看可能是问题)并且如果我想要添加更多正则表达式将会造成问题/更换.

这是另一个更友好(和命令)并且有效的版本,但看起来很平庸:

(defn trim1 
  " Not so functional version"
  [raw-string]
  (def string (atom raw-string))
  (reset! string (clojure.string/replace @string #"([^\\(\[{@~`'])(\(|\[|\{)" "$1 $2"))
  (reset! string (clojure.string/replace @string #"(\)|\]|})(\[|\(|\{)" "$1 $2"))
  (reset! string (clojure.string/replace @string #"[ \t]*(\)|\]|\})" "$1"))
  (reset! string (clojure.string/replace @string #"[ \t]{2,}" " "))
  (reset! string (clojure.string/replace @string #"(\)|\]|\})[ \t]*(?=(\)|\]|\}))" "$1"))
  (reset! string (clojure.string/replace @string #"(\(|\[|\{)[ \t]*(?=(\(|\[|\{))" "$1"))
  (reset! string (clojure.string/replace @string #"^[ \t]*" ""))
  (reset! string (clojure.string/replace @string #"(\\\{|\\\(|\\\[) " "$1  "))
  (reset! string (clojure.string/replace @string #"(\{|\(|\[) " "$1"))
  (reset! string (clojure.string/replace @string #" ('|`) (\(|\[|\{)" " $1$2")))
Run Code Online (Sandbox Code Playgroud)

我希望找到一个看起来像这样的解决方案:

  • 将regexp和替换存储在关联列表中: ['(#"^[ \t]*" "")]
  • 然后做一些类似的事情 (reduce trim-fn replacement-list string)

reduce如果它是可实现的,那部分将非常酷.但是,如果不可能,我会欢迎任何比这两个更好的解决方案.

Bey*_*mor 8

(def trim-patterns 
  [[#"([^\\(\[{@~`'])(\(|\[|\{)" "$1 $2"]
   [#"(\)|\]|})(\[|\(|\{)" "$1 $2"]
   [#"[ \t]*(\)|\]|\})" "$1"]
   [#"[ \t]{2,}" " "]
   [#"(\)|\]|\})[ \t]*(?=(\)|\]|\}))" "$1"]
   [#"(\(|\[|\{)[ \t]*(?=(\(|\[|\{))" "$1"]
   [#"^[ \t]*" ""]
   [#"(\\\{|\\\(|\\\[) " "$1  "]
   [#"(\{|\(|\[) " "$1"]
   [#" ('|`) (\(|\[|\{)" " $1$2"]])

(defn trim
  [s]
  (reduce
    (fn [s [match replacement]]
      (clojure.string/replace s match replacement))
    s trim-patterns))
Run Code Online (Sandbox Code Playgroud)