Regex clojure初学者:不同字符的标记化列表

Regex clojure初学者:不同字符的标记化列表,regex,clojure,tokenize,Regex,Clojure,Tokenize,所以我知道这不是解决这个问题的最佳方法,但我正在尝试遍历输入文件中的一系列行,这些行最终都是表达式。我有一个表达式列表,由于splitthelist函数,每个表达式都有自己的列表。我的下一步是将字符替换为id,将int替换为int,将+或-替换为addop。我有正则表达式来确定我的符号是否匹配其中的任何一个,但是当我尝试替换它们时,我只能得到最后一个我调用的for循环来留下任何持久的结果。我知道它的根源是函数式编程的工作方式,但我不知道该程序的运行轨迹,以及如何替换每种不同类型的输入并将结果保存

所以我知道这不是解决这个问题的最佳方法,但我正在尝试遍历输入文件中的一系列行,这些行最终都是表达式。我有一个表达式列表,由于splitthelist函数,每个表达式都有自己的列表。我的下一步是将字符替换为
id
,将int替换为
int
,将+或-替换为
addop
。我有正则表达式来确定我的符号是否匹配其中的任何一个,但是当我尝试替换它们时,我只能得到最后一个我调用的for循环来留下任何持久的结果。我知道它的根源是函数式编程的工作方式,但我不知道该程序的运行轨迹,以及如何替换每种不同类型的输入并将结果保存在一个列表中

(def reint #"\d++")
(def reid #"[a-zA-Z]+")
(def readdop #"\+|\-")

(def lines (into () (into () (clojure.string/split-lines (slurp "input.txt")) )))

(defn split-the-line [line] (clojure.string/split line #" " ))

(defn split-the-list  [] (for [x (into [] lines)] (split-the-line x)))

(defn tokenize-the-line [line] 
(for [x line] (clojure.string/replace x reid "id")) 
(for [x line] (clojure.string/replace x reint "int")) 
(for [x line] (clojure.string/replace x readdop "addop")))

(defn tokenize-the-list [] (for [x (into [] (split-the-list) )] (tokenize-the-line x)))

正如你可能知道的,我对函数式编程非常陌生,所以欢迎任何建议

您正在使用一个
do
块,该块计算多个表达式(通常用于副作用),然后返回最后一个表达式。您无法看到它,因为
fn
(因此
defn
)隐式包含一个。因此,这些线

(for [x line] (clojure.string/replace x reid "id")) 
(for [x line] (clojure.string/replace x reint "int")) 
被评估(分成两个不同的惰性序列),然后丢弃。 为了让它们影响返回值,您必须捕获它们的返回值,并在下一轮替换中使用它们。 在这种情况下,我认为最自然的替换方法是线程宏
->

(for [x line] 
     (-> x 
         (clojure.string/replace reid "id")
         (clojure.string/replace reint "int")
         (clojure.string/replace readdop "addop")))
这将创建一个代码,
reid
替换为
x
作为第一个参数,然后
reint
替换为第一个参数的结果,依此类推


或者,您可以通过使用
comp
来编写匿名函数,如
(fn[s](clojure.string/replace s reid“id”)
(部分应用
replace
)。在命令式世界中,我们非常习惯于运行几个“在适当位置对数据进行bash”的过程-在函数世界中,您通常会将多个函数组合在一起执行所有操作,然后运行结果。

为什么要将所有这些
都用到
?这些函数在代码中什么都不做。非常感谢,这让生活变得更轻松了。