所以我可以这样做:
CL-USER> (format t "~80<~a~;~a~;~a~;~a~>~%" "hello" "how are you" "i'm fine" "no you're not")
hello how are you i'm fine no you're not
按指定的方式在4跨度上均匀分隔4个字符串。
但是,我希望传递一个字符串列表,并根据列表中的许多字符串来确定它们的合理性。
这些都没有:
CL-USER> (format t "~{~80<~a~;~>~}~%" '(1 2 3 4 5 6))
1
2
3
4
5
6
CL-USER> (format t "~80<~{~a~;~}~>~%" '(1 2 3 4 5 6))
; Evaluation aborted on #<SB-FORMAT:FORMAT-ERROR {126651E1}>.
; ~; not contained within either ~[...~] or ~<...~>
有办法做到这一点吗?
答案 0 :(得分:7)
您可以使用(format stream (format nil ...))
执行此操作,您可以使用format
生成对齐格式控件:
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil (format nil "|~~40<~{~a~^~~;~}~~>|" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
如果您不想为外部format
生成整个格式控件,可以使用~?
的某种变体来递归处理字符串和一些参数:
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5)))
"|1 2 3 4 5|"
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10)))
"|1 2 3 4 5 6 7 8 9 10|"
CL-USER> (format nil "|~@?|" (format nil "~~40<~{~a~^~~;~}~~>" '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)))
"|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15|"
使用~?
的递归处理只允许您使用参数列表处理另一个格式控件;它没有给你一种拼接新格式字符串的方法。似乎被证明的文本必须存在于控制字符串中,因此您真的需要一种方法来拼接已包含所需文本的控件字符串。
虽然其中第一个似乎更简单,但它存在危险因为你将打印的文本放入另一个格式字符串中,而你在第二种情况下没有这样做。在第一种情况下,如果这些数字中的任何一个被格式指令替换,外部格式将尝试处理它们。在第二种情况下,这不会发生。因此,我想我会建议第二个。