string - 在 Clojure 中以函数式方式重写这个修剪函数

标签 string clojure reduce

我有这个功能(来自 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/

相关文章:

python - pickle cython类

javascript - 按句子 chop 文本分割

java - 从 Clojure 中的字符串解析命令行参数

clojure - 使用无点样式定义的文档函数

c++ - 使用 string::find 和 string::substr 拆分字符串的函数返回错误的标记

c - 接收字符串消息时出现段错误

clojure - 键作为映射的函数,反之亦然,在 Clojure 中如何以相同的方式工作?

Javascript 减少陷阱 - 跳过第一次迭代?

ios - Xcode:将结构化数据放入 Localizable.strings 文件

python - 在 python 字典中打印值时的间距