我如何阅读以下文件,其中包含带有标题和空格或制表符分隔的数据列,通常是lisp。
我还想将数据放入包含行的列表列表中。
另外,如何在常见的lisp
中获得日期差异 ID YR MO DA YrM MoM DaM
100 2010 2 20 2010 8 30
110 2010 4 30 2010 9 12
112 2010 8 20 2010 10 20
答案 0 :(得分:10)
从流中读取包含NUMCOLS列的表的功能
它假设可以使用READ
读取表格中的项目。 (PEEK-CHAR T ...)
测试流中是否还有一些非空白文本。
(defun read-a-table (stream numcols)
(cons (loop repeat numcols collect (read stream))
(loop while (peek-char t stream nil nil)
collect (loop repeat numcols collect (read stream)))))
以下是两个示例函数
一个从文件中读取一个表,另一个从字符串中读取一个表。
(defun read-a-table-from-file (file numcols)
(with-open-file (stream file)
(read-a-table stream numcols)))
(defun read-a-table-from-string (string numcols)
(with-input-from-string (stream string)
(read-a-table stream numcols)))
让我们用字符串测试它:
(defun test ()
(read-a-table-from-string "ID YR MO DA YrM MoM DaM
100 2010 2 20 2010 8 30
110 2010 4 30 2010 9 12
112 2010 8 20 2010 10 20"
7))
执行测试
CL-USER 15 > (test)
((ID YR MO DA YRM MOM DAM)
(100 2010 2 20 2010 8 30)
(110 2010 4 30 2010 9 12)
(112 2010 8 20 2010 10 20))
答案 1 :(得分:4)
您可以使用READ-LINE从流中读取整行。如果您有文件名,则使用WITH-OPEN-FILE将流连接到文件。将每一行作为列表的元素意味着使用LOOP:
(loop for line = (read-line stream nil 'eof) until (eq line 'eof) collect line)
要将每行拆分成列需要基本Common Lisp中的一些工作,但是这个cl-utilities包中包含一个名为SPLIT-SEQUENCE的函数,它可以将分隔的字符串拆分为一个标记列表。
首次搜索日期处理产生了http://common-lisp.net/project/cl-date-calc/index.html,它具有DELTA-DAYS功能。
答案 2 :(得分:1)
使用cl-ppcre。 “拆分”功能非常适用于此,我在我的程序中使用它。只需将其设置为使用#\ Space作为分隔符。