如何优雅地将字符串
"1 2 3 4 5 6 7"
转换为列表(1 2 3 4 5 6 7)
?我正在使用 CLISP。
这是一个递归解决方案。
;Turns a string into a stream so it can be read into a list
(defun string-to-list (str)
(if (not (streamp str))
(string-to-list (make-string-input-stream str))
(if (listen str)
(cons (read str) (string-to-list str))
nil)))
parse-integer
。
例如,使用
loop
:
(let ((string "1 2 3"))
(loop :for (integer position) := (multiple-value-list
(parse-integer string
:start (or position 0)
:junk-allowed t))
:while integer
:collect integer))
⇒
(1 2 3)
如果您需要更好地控制拆分,请使用
split-sequence
或 cl-ppcre
库。
如果您需要解析更通用的数字格式,请使用
parse-number
库。
可从 Quicklisp 获取库。
提示:看看 with-input-from-string。
(with-input-from-string (s "1 2 3 4 5 6 7" :index i :start 0 :end 13)
(list (read s) (read s) (read s) (read s) (read s) (read s)))
(1 2 3 4 5 6 7)
它可以工作,但我觉得它不是那么优雅,因为有很多
read
调用。
再次感谢!
我认为这可能有用:
(setf s "1 2 3 4 5 6 7")
(setf L-temp (coerce s 'list))
这将创建一个以空格为元素的列表。删除空格:
(setf L-final (remove #\Space L-temp))
我认为斯万特是对的。我之前的尝试没有成功。这是另一种尝试。我使用连接将字符串更改为列表表示形式。然后我使用 read-from-string 将字符串 (s-2) 转换为实际列表。
(setf s-0 "1 2 3 4 5 6 7")
(setf s-1 (concatenate 'string "(" s ")" ))
(setf s-2 (read-from-string s-1))
我将它变成这样的函数:
(defun from-string-to-list (s)
(let ((L (read-from-string
(concatenate 'string "(" s ")"))))
L))
“let”和“L”的唯一目的是使函数 from-string-tolist 仅返回列表而不返回多个值。 read-from-string 返回两个值:我认为是列表和字符串的大小。
这样就行了,
(with-input-from-string (s "1 2 3 4 5")
(let ((r nil))
(do ((line (read s nil 'eof)
(read s nil 'eof)))
((eql line 'eof))
(push line r))
(reverse r)))
您还可以使用地图功能:
(map 'list #'identity "1 2 3 4 5 6 7")