5

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

(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 "  
4

1 回答 1

17

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

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

但是,您可能有许多不能被三整除的参数,在这种情况下,您需要提前终止迭代。~^如果没有更多参数,您可以使用格式指令来中断。由于您可能会在第一个或第二个参数之后出现这种情况,因此您应该在这些位置之后添加其中一个。以下是带有零个、一个和两个尾随参数的情况的示例:

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
"

当元素的数量可以被三整除时,您可能不想要最后的换行符,在这种情况下,您也可以~^在换行符之前添加 a:

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 波浪号左大括号:迭代

~{str~}

这是一个迭代构造。参数应该是一个列表,它被用作一组参数,就像对format的递归调用一样。字符串 str被反复用作控制字符串。每次迭代都可以吸收列表中任意数量的元素作为参数;如果str自己用完两个参数,那么每次循环都会用完列表的两个元素。如果在任何迭代步骤之前列表为空,则迭代终止。另外,如果给定前缀参数n,那么str 的处理最多会重复n次. 最后,该~^指令可用于提前终止迭代。

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

于 2013-10-22T15:51:35.990 回答