String Clojure:第一个空格分隔字符的印章
我想分析和筛选一个如下所示的文件:String Clojure:第一个空格分隔字符的印章,string,parsing,filter,clojure,String,Parsing,Filter,Clojure,我想分析和筛选一个如下所示的文件: @@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))) 但是,
@@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.
我认为有一些序列魔法可以做到这一点。我就是想不出一个优雅的解决方案。我会用以下方式定义函数:
(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
的组合为我提供了输入文件中的一系列行<代码>打开确保文件在我完成时正确关闭。我对查找@
后跟数字和一些空格的每一行应用一个正则表达式
重新查找
返回包含三项的向量:
- 整条线都匹配
- 编号(正则表达式中的第一个组)
- 行的其余部分(正则表达式中的第二组)
for
语句中使用解构将它们绑定到number
和line
(我对匹配的整行不感兴趣,所以忽略它)。我使用:when
过滤所选sel行
,并仅产生(剩余的)行
因为我只希望文件中有一个匹配项,所以我只返回由为
构建的序列中的第一项。由于for
、map
和line seq
的惰性,这也会在找到项目后停止读取文件
如果您对行进行大量查找,我建议您将整个文件加载到内存中,而不是每次都读取它。前面给出的答案使用
line seq
和正则表达式组的解构对于给定的用例很有效
在一般情况下,您只需要对字符串进行操作,clojure.core包含subs
函数
subs
是使用java互操作和java字符串类的substring方法实现的
user=> (subs "abcdef" 1)
"bcdef"
user=> (subs "abcdef" 2 4)
"cd"
另一个解决方案是使用一个函数解析器库,比如dj-peg(我写的) 然后你可以写下:
(require '[dj-peg :as p])
(let [line "@@1 the remaining line\n"
initial (p/token #"@@\d+\s+)]
(second (p/parse initial line)))
函数parse使用p/token返回的解析器来解析第行中的文本。它将返回一个向量,第一个值作为解析的结果,第二个值是剩余的输入。因此,如果我们叫第二个,我们就得到了剩余的线路。运行此命令将返回
"the remaining line\n"
我建议你去图书馆看看。它是以伪读写编程风格编写的,因此源代码读起来相当流畅。阅读源代码后,您应该能够理解解析模型。应该使用open表单在周围的
中创建读取器
。谢谢。我是clojure的新手,您能提供更多关于内存加载的信息吗?也许是一些医生?
"the remaining line\n"