Lisp多次格式化一个字符

时间:2013-11-19 13:34:26

标签: format lisp common-lisp

我正在寻找输出角色的方法 多次使用格式。这可能吗?有人可以填写 在_?_中,以便该示例有效吗?

(let ((n 3))
  (format nil "_?_" _?_ #\* _?_ ))

应该返回

=> "***"

4 个答案:

答案 0 :(得分:7)

很高兴看到这么多解决方案:~A,〜<和〜{到目前为止。

〜@ {iteration构造提供了一个简洁的解决方案:

(format nil "~v@{~A~:*~}" 3 #\*)

答案 1 :(得分:5)

如果你使用~A指令,你可以完全按照你建议的形式得到它,即

(let ((n 3))
  (format nil "_?_" _?_ #\* _?_ ))

有三个格式参数。但是,如果使用~<,实际上只需要两个格式参数即可。如果您在format已经生成的其他字符串中不需要此字符串,您也可以使用make-string创建字符串。

使用Tilde A(~A)

您可以打印字符并指定最小宽度和与填充字符相同的字符。例如,使用~v,,,vA和两个参数,可以确保打印一些字符,以及填充字符是什么。

CL-USER> (let ((n 3))
           (format nil "~v,,,vA"
                   n     ; number of characters that must be printed
                   #\*   ; character to use as padding
                   #\*)) ; character to print with ~A
"***"

CL-USER> (let ((n 3))
           (format nil "~v,,,vA" n #\* #\*)) 
"***"

CL-USER> (let ((n 10))
           (format nil "~v,,,vA" n #\* #\*))
"**********"

这使用full form of ~A

  

~mincol,colinc,minpad,padcharA是〜A的完整形式,它允许   控制填充。字符串填充在右侧(或在   如果使用@修饰符,则至少离开,至少有minpad副本   padchar;然后在a处插入填充字符colinc字符   直到总宽度至少为mincol的时间。默认值为0表示   mincol和minpad,1表示colinc,以及padchar的空格字符。

以及v

  

代替指令的前缀参数,可以使用V(或v)。   在这种情况下,format将args中的参数作为参数   指示。参数应该是整数或字符。如果arg   V参数使用的是nil,效果就像参数一样   被省略了。 #可用于代替前缀参数;它   表示剩余待处理的args数。使用时   在递归格式内,在〜?的上下文中?或〜{,#前缀   参数表示剩余的格式参数的数量   递归电话。

使用Tilde Less Than(〜&lt;)

还有一种不常用的格式指令,波形符号小于,用于证​​明。它需要一个格式字符串并使s

  

〜mincol,colinc,minpad,padchar&LT; STR〜&GT;

     

这证明了在一个字段中处理str所产生的文本   最小的mincol列宽。 str可以分为段   〜;,在这种情况下,间距在文本之间均匀分配   段。

我们可以(ab)通过传递一个空格式字符串并只指定宽度和填充字符来使用它:

CL-USER> (let ((n 3))
           (format nil "~v,,,v<~>"
                   n     ; width
                   #\*)) ; padding character
"***"

CL-USER> (let ((n 5))
           (format nil "~v,,,v<~>" n #\*))
"*****"

只需创建一个字符串

当然,除非你需要格式化的其他字符串中的 ,否则你应该按照wvxvw的建议进行操作,只需使用make-string

(make-string 3 :initial-element #\*)

其他替代方案

format非常灵活,正如这个和其他答案所指出的那样,有很多方法可以做到这一点。我试图坚持那些应该在一次通过中执行此操作并且不进行显式迭代的那些,但这也可以通过format迭代完成,因为Lars Brinkhoffwvxvw指向进行。

答案 2 :(得分:4)

(format nil "~a~:*~a~:*~a~:*" #\*)
"***"

或者详细阐述约书亚·泰勒的答案:

(format nil "~v{~a~:*~}" 3 '(#\*))

这是实现这一目标的一种方式。不要被format指令中的星号混淆,它们是控制字符,而不是正在打印的字符。


然而,就效率而言:

(make-string 3 :initial-element #\*)

将是实现相同效果的首选方式。

答案 3 :(得分:3)

与Lars的答案一样,但是我们用~C来写字符,而不是使用~A打印机:

(format nil "~v@{~C~:*~}" 3 #\*)

使用类似write-char的字符编写字符比打印Lisp对象更简单。打印机有很多要观察的上下文,必须找到打印对象的正确方法。 OTOH,类似于WRITE-CHAR,只是将一个字符写入流中。