2

我有一种感觉,我的问题的答案与 Clojure 的惰性评估有关(我对此仍然很模糊......)

所以我有一个功能:

(defn fix-str-old [string]
  (let [words (->> string
                   (clojure.string/split-lines) 
                   (map #(clojure.string/replace % #"\W" "")))]
    (apply str (interleave words (repeat " ")))))

基本上,它只需要一个带有非字母数字字符、字符、返回字符、换行符等的古怪句子代替空格,然后将其转换为常规句子。如果您好奇,这样做的原因是每当我尝试复制某些 PDF 文件时,它都会在单词之间插入换行符和其他神秘字符。

这是一个例子:

(fix-str "A 
  block 
  of    
  SQL   
  statements    
  that  
  must  
  all   
  complete  
   successfully 
  before    
  returning 
  or    
  changing  
  anything  ")

==> "A block of SQL statements that must all complete  successfully before returning or changing anything"

它在 REPL 中运行良好,但是当它在一个小摇摆 gui 中进行评估时,你会得到:

"AblockofSQLstatementsthatmustallcompletesuccessfullybeforereturningorchanginganything "

(注意字符串末尾的空格)

我很确定这是因为我对 Clojure 如何处理惰性序列的理解存在一些差距,所以我创建了这个只执行正则表达式操作的函数。

(defn fix-str [string]
  (-> string
      (clojure.string/replace #"[ \t\n\r]+" " ")
      (clojure.string/replace #"[^a-zA-Z0-9 ]" "")
      (clojure.string/trimr)))

这不是懒惰的,并且在 REPL 和 GUI 中都可以正常工作。

注意:我还尝试将 doall 语句放在原始函数中的各个位置,虽然我认为确保它强制评估惰性序列可能是有意义的,但我也无法让它工作。

所以我的问题不是第一种方法是否是修复字符串的好方法,而是为什么我在 REPL 和我的 GUI 中得到不同的结果。

4

1 回答 1

2

在这里,懒惰不应该是你的问题,因为它会(apply str ...)强制实现输出map(并且因为这里没有绑定,这通常是你认为懒惰是罪魁祸首的第一条线索)。

在我看来,来自 GUI 的行尾发生了一些奇怪的事情,这split-lines并没有分割任何东西。该功能拆分\n\r\n- 也许您以某种方式\r从 GUI 获得行尾?您可以通过将其添加到函数的开头来验证这一点fix-str

(doseq [c string] (println (int c)))
于 2013-05-13T21:52:13.123 回答