使Clojure识别和隔离文件中的行

5

我想让Clojure读取一个文件,将第一行放入一个变量中,将其余部分放入另一个变量中。

我似乎无法找到如何实现这一点的方法,如果有人能够帮我解决问题,我将不胜感激。

2个回答

4
;; for Clojure 1.1
(require '[clojure.contrib.duck-streams :as io])
;; for bleeding edge
(require '[clojure.java.io :as io])

(with-open [fr (io/reader "/path/to/the/file")]
  (let [[first-line & other-lines] (doall (line-seq fr))]
    ;; do stuff with the lines below...
    ...))

更新: 啊,刚才意识到我从问题中取出的“其余部分”是指“文件中的其余行”,因此在上面的代码中other-lines是除第一行外文件中所有行的序列。

如果你需要“包含文件其余内容的字符串”,则可以使用上面的代码,但是需要使用 (require '[clojure.contrib.str-utils2 :as str]) / (require '[clojure.string :as str])(取决于你使用的Clojure版本),然后说(str/join "\n" other-lines)other-lines重新连接成一个字符串; 或者,您也可以使用类似以下的东西:

(let [contents (slurp "/path/to/the/file")
      [first-line rest-of-file] (.split #"\n" contents 2)]
  ...)

2
Clojure头部:
(require '[clojure.string :as str])
(let [[f & r] (str/split (slurp "foo.txt") #"\n")]
   ... do something with f and r ...)

ED: 不知何故,我没有认出Michał的答案,曾考虑删除它,但由于它略有不同并展示了clojure.string.split,我决定保留。


当我将此输出到文件时,文件中会出现很多 [\。你知道为什么吗? - implmentor
在这个解决方案中,slurp 返回的字符串被分成了多行。也就是说,(str/split str #"\n") 会返回一个线性数组。然后,第一行被绑定到 f,其余向量被绑定到 r。还可以参考 Michał 的答案的第二段。 - danlei
我尝试了你的解决方案并执行了(println(str f r))。第一行完美无缺,但其余部分都在括号(错别字)和引号中。就像这样:这是第一行。(“”“这是”“其他行”)。有什么方法可以摆脱括号和引号?看不出Michael的解决方案如何解决这个问题。 - implmentor
(str/split "string\nwith\nnewlines" #"\n") 返回一个由每行组成的 PersistentVector。为了连接这些行,你可以使用 (str/join "\n" seq-of-strings)。这就是 Michał 在他的回答的第二段中所说的意思。换句话说,(str/join "\n" ...) 是 (str/split ... #"\n") 的反函数。因此,(let [[f & r] (str/split str #"\n")] [f (str/join "\n" r)]) 产生的结果与 (seq (.split #"\n" str)) 相同。结果用括号括起来的原因是,在解构时返回了向量(PersistentVector$ChunkedSeq)上的序列,注意 (class [1 2 3]) 与 (class (rest [1 2 3])) 的区别。 - danlei
换句话说:如果你想要“包含文件其余内容的字符串”,那么使用Michał的最后一段代码(.split #"\n" str 2)是正确的方法,但如果你想要逐行读取,你可以使用Michał的第一段代码或者我的解决方案。我之前评论中有错别字:(seq (.split #"\n" str 2)) - danlei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接