代码之家  ›  专栏  ›  技术社区  ›  Gradient

在格式的迭代指令中使用变量填充

  •  1
  • Gradient  · 技术社区  · 7 年前

    有没有一种方法可以做到以下几点?

    (format t "~{~va~}" '("aa" "bb" "cc") 4)
    

    我需要遍历一个列表。该列表中的每个元素都应该用一个可变数量的空格填充(在运行时指定,因此我不能使用“~4a”)。

    或者更一般地说,在格式的参数列表中有没有一种引用特定参数的方法?

    3 回复  |  直到 7 年前
        1
  •  1
  •   Gwang-Jin Kim    7 年前

    嵌套 format 功能,你可以做你想做的。

    (format t (format nil "~~{~~~Aa~~}" 4) '("aa" "bb" "cc"))
    ;; returns: aa  bb  cc  
    

    这里内部 格式 指令: 这个 nil 作为第一个论点, 格式 返回字符串。

    (format nil "~~{~~~Aa~~}" 4)
    ;; returns: "~{~4a~}" - and this is exactly what you want to give
    ;; to the outer `format` as second argument!
    

    当然,您可以为此编写函数:

    (defun format-by-padding-over (lst padding)
      (format t (format nil "~~{~~~Aa~~}" padding) lst))
    

    然后:

    (format-by-padding-over '("aa" "bb" "cc") 4)
    ;; aa  bb  cc  
    ;; NIL
    

    我学会了这个技巧 here 来自@sylvester(非常感谢!).

        2
  •  0
  •   Svante    7 年前

    你也可以在列表中插入重复的填充:

    (format t "~{~va~}"
            (mapcan (lambda (element)
                      (list 4 element))
                    list))
    
        3
  •  0
  •   coredump    7 年前

    您可以使用嵌套的格式函数构建格式控制字符串,但是必须注意转义tildes。使用正则表达式(使用cl-ppcre)时,可以使用树定义正则表达式,例如 (:alternation #\\ #\*) 这有助于防止与逃避特殊角色相关的bug和头痛。同样可以使用格式字符串,使用 format-string-builder ,在QuickLisp中提供:

    (lambda (v)
      (make-format-string `((:map () (:str ,v)))))
    

    返回一个闭包,可用于生成格式字符串:

    (funcall * 10)
    => "~{~10a~}"