Regex clojure初学者:不同字符的标记化列表
所以我知道这不是解决这个问题的最佳方法,但我正在尝试遍历输入文件中的一系列行,这些行最终都是表达式。我有一个表达式列表,由于splitthelist函数,每个表达式都有自己的列表。我的下一步是将字符替换为Regex clojure初学者:不同字符的标记化列表,regex,clojure,tokenize,Regex,Clojure,Tokenize,所以我知道这不是解决这个问题的最佳方法,但我正在尝试遍历输入文件中的一系列行,这些行最终都是表达式。我有一个表达式列表,由于splitthelist函数,每个表达式都有自己的列表。我的下一步是将字符替换为id,将int替换为int,将+或-替换为addop。我有正则表达式来确定我的符号是否匹配其中的任何一个,但是当我尝试替换它们时,我只能得到最后一个我调用的for循环来留下任何持久的结果。我知道它的根源是函数式编程的工作方式,但我不知道该程序的运行轨迹,以及如何替换每种不同类型的输入并将结果保存
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”的过程-在函数世界中,您通常会将多个函数组合在一起执行所有操作,然后运行结果。为什么要将所有这些都用到?这些函数在代码中什么都不做。非常感谢,这让生活变得更轻松了。