我有这个功能(来自 program 的摘录),我想以更具吸引力/功能性/惯用的方式重写。
它应该从 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"))
我对它现在的样子不是很满意,因为乍一看很难弄清楚它是如何工作的(布局可能是问题所在),如果我想添加它会带来问题更多正则表达式/替换。
这是另一个更友好(和命令式)并且有效但看起来平庸的版本:
(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
部分如果可以实现的话会非常棒。但是,如果不可能,我会欢迎任何其他比这两个更好的解决方案。
最佳答案
(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))
关于string - 在 Clojure 中以函数式方式重写这个修剪函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20585991/