2013-12-14 36 views
2

我有這個功能(摘自program),我想以更具吸引力/功能/慣用的方式重寫。
它應該從s表達式中刪除任何不必要的空格。在Clojure中以功能方式重寫此修剪功能

(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")) 

我不是很滿意,它看起來像現在,因爲它很難弄清楚它是如何工作的第一眼(佈局可能是問題),如果我要會造成問題的辦法曾經想要添加更多的正則表達式/替換。

這裏的另一個版本,更友好(和必要的)和作品,但相貌平庸:

(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"))) 

我希望的,看起來像一個解決方案:

  • 商店正則表達式和關聯列表中的替換:['(#"^[ \t]*" "")]
  • 然後做類似(reduce trim-fn replacement-list string)

如果可以實現,reduce部分將非常酷。但是,如果不可能的話,我會歡迎任何比這兩個更好的解決方案。

回答

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))