具有cl:格式的列表中每隔三个单词后的换行符

时间:2013-10-22 15:38:15

标签: format lisp common-lisp

如何在列表中的每第三个参数后添加回车符(使用~%)? 例如,我现在有:

(format nil "~{~a ~}" (list '"one" '"two" '"three" '"four" '"five" '"six" '"seven" '"eight" '"nine" '"ten"))  
;=> "one two three four five six seven eight nine ten " 

但我想:

;=> "one two three  
; four five six  
; seven eight nine  
; ten "  

1 个答案:

答案 0 :(得分:17)

str中的格式字符串~{str~}可以在每次迭代时使用列表中的多个参数。这意味着如果您有一个保证可被3整除的参数列表,则可以使用类似~{~a ~a ~a~%~}的格式字符串。这是一个例子:

CL-USER> (format nil "~{~a ~a ~a~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6
"

但是,您可能有许多不能被3整除的参数,在这种情况下,您需要尽早终止迭代。如果没有更多参数,您可以使用格式指令~^来中断。由于在第一个或第二个参数之后你可能会遇到这种情况,你应该在这些地方之后添加其中一个。以下是包含零个,一个和两个尾随参数的案例示例:

CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4))
"1 2 3
4"
CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4 5))
"1 2 3
4 5"
CL-USER> (format nil "~{~a~^ ~a~^ ~a~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6
"

当元素数量可被3整除时,您可能不需要最终换行符,在这种情况下,您也可以在换行符之前添加~^

CL-USER> (format nil "~{~a~^ ~a~^ ~a~^~%~}" '(1 2 3 4 5 6))
"1 2 3
4 5 6"

这种结构特别适合编写分隔列表:

CL-USER> (format nil "write(~{~a~^,~})" '("fd" "buf" "count"))
"write(fd,buf,count)"

这些格式指令(及其变体)在HyperSpec中有更详细的描述(链接页面中的内容多于此处引用的内容):

  

22.3.7.4 Tilde Left-Brace: Iteration

     

〜{STR〜}

     

这是一个迭代构造。参数应该是列表,其中   用作一组参数,就像对format的递归调用一样。   重复使用 string str 作为控制字符串。每   迭代可以吸收尽可能多的列表元素   参数;如果 str 本身使用了两个参数,那么就是两个元素   每次循环时, list 的内容都会被用完。如果在任何之前   迭代步骤 list 为空,然后迭代终止。   此外,如果给出了前缀参数 n ,那么最多只有 n   重复处理 str 。最后,~^指令可以   用于过早终止迭代。

您可能也对这些问题感兴趣: