我想解析和过滤一个如下所示的文件:
@@1 Row one.
@@2 Row two.
我已经能够使用以下代码对行进行过滤:
(defn parse-text-cms [sel-row]
(let [f_data (st/split #"@@" (slurp "cms/tb_cms.txt"))]
;(prn (map #(take 1 %) f_data))))
(filter #(= (first (take 1 %)) sel-row) f_data)))
但是,这段代码给了我(如果 sel-row=1):
1 Row one.
我想砍掉 1 和后面的空格,这样就可以:
Row one.
我认为有一些序列魔法可以做到这一点。我只是想不出一个优雅的解决方案。
最佳答案
我将按以下方式定义该函数:
(defn parse-text-cms [sel-row]
(with-open [input (clojure.java.io/reader "cms/tb_cms.txt")]
(first
(for [[_ number line] (map (partial re-find #"@@(\d)+\s+(.*)")
(line-seq input))
:when (= number (str sel-row))]
line))))
line-seq
和 reader
的组合为我提供了输入文件中的行序列。 with-open
确保文件在我完成后正确关闭。我将正则表达式应用于查找 @@
的每一行,后跟数字和一些空格。
re-find
返回包含三个项目的向量:
- 整个匹配行
- 数字(正则表达式中的第一组)
- 该行的其余部分(正则表达式中的第二组)
我使用 for
语句中的解构将它们绑定(bind)到 number
和 line
(我对整个匹配行不感兴趣,所以我忽略了这一点)。我使用 :when
过滤选定的 sel-row
,并仅生成(其余的)行
。
由于我只期望文件中存在一个匹配项,因此我仅返回 for
构建的序列中的第一项。由于 for
、map
和 line-seq
的惰性,这也会在找到项目后停止读取文件。
如果您对行进行大量查找,我建议将整个文件加载到内存中,而不是每次都读取它。
关于string - Clojure:删除第一个空格分隔的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8405193/