只需编写一个简单的程序来学习如何操作列表。外部文件有两列:bookname ISBN-no。样品:
+ How to Read the Bible: History, Prophecy, Literature--Why Modern Readers Need to Know the Difference and What It Means for Faith Today - ISBN-13: 978-0195383300
+ Who Wrote the Bible? - ISBN-13: 978-0060630355
这些功能将允许用户选择并生成按ISBN-no或bookname排序的另一个文件。
我开始写它但是一小时后发现我的方法并不是很糟糕。核心逻辑就像一个解析器:
(defun proc-ls-str (ls)
(let ((str+ "")
(str- "")
(first- t)
(in+ t))
(cond ((null ls)
(progn
(format t "(never this) str+ is ~a str- is ~a~%" str+ str-)))
((equal (car ls) '+)
(progn
(format t "(only this) str+ is ~a " str+)
(setf str+ "+")
(setf first- t)))
((equal (car ls) '-)
(setf first- nil)
(setf in+ nil))
(t (progn
(proc-ls-str (cdr ls)))))))
它最终会起作用,事实上我在Swift中编写了一个类似的程序来处理逗号分隔的允许引用。但它并没有真正学习Lisp。
有关我的方法的任何建议吗?我能阅读的任何样本。 (源代码不是书,有很多。)
答案 0 :(得分:1)
我认为您可能会对解析此类内容的一些最简单的方法感到失望,但在Common Lisp中并不是特别难。首先,让我们将该文件内容放在一个字符串中(我们可以稍后通过流读取字符串):
(defparameter *file-content*
"+ How to Read the Bible: History, Prophecy, Literature--Why Modern Readers Need to Know the Difference and What It Means for Faith Today - ISBN-13: 978-0195383300
+ Who Wrote the Bible? - ISBN-13: 978-0060630355
")
现在让我们定义一个 parse-file 函数,该函数从流中读取行并通过剥离前缀并根据分隔符字符串的出现拆分余数来将它们分成组件。我们可以指定前缀和分隔符,但我已根据文件内容提供了默认值。
(defun parse-file (&optional
(in *standard-input*)
&key
(prefix "+ ")
(separator " - ISBN-13: "))
(loop
with prefixlen = (length prefix)
with seplen = (length separator)
for line = (read-line in nil nil)
for split = (search separator line)
until (null line)
collect (cons (subseq line prefixlen split)
(subseq line (+ seplen split)))))
现在我们可以使用 with-input-from-string 将文件内容作为流获取,我们可以解析流:
CL-USER> (with-input-from-string (input *file-content*)
(parse-file input))
(("How to Read the Bible: History, Prophecy, Literature--Why Modern Readers Need to Know the Difference and What It Means for Faith Today"
. "978-0195383300")
("Who Wrote the Bible?" . "978-0060630355"))