Skip to content

LISP - 字符串连接

Lisp - 字符串拼接(String Concatenation)

Section titled “Lisp - 字符串拼接(String Concatenation)”

Common Lisp 提供了几种强大且灵活的方法用于字符串拼接(string concatenation)和格式化。选择哪种方法取决于任务的复杂性和性能考量。本指南涵盖了最常用的技术,从简单的连接到复杂的程序化字符串构造。

  • concatenate:最适合简单、直接拼接少量字符串。
  • format:最通用的工具,用于创建嵌入数据的复杂格式化字符串。
  • with-output-to-string:最适合高效地以增量方式构建字符串,例如在循环中。

concatenate 函数是一个通用序列函数。要将其用于字符串,你必须将 'string 指定为结果序列的类型。然后,它接受任意数量的字符串作为参数,并将它们连接在一起。

以下是如何拼接两个简单字符串。请注意,结果是一个新字符串。

;; 第一个参数指定输出类型。
(concatenate 'string "Hello, " "Modern " "Lisp!")
"Hello, Modern Lisp!"

format 是 Lisp 文本格式化能力的“瑞士军刀”。它可以从模板构造字符串,无缝集成各种数据类型。format 的第一个参数是目标(destination)。目标为 nil 表示 format 将结果作为新字符串返回。

常用的 format 指令(directives)包括:

  • ~a:美观指令(Aesthetic directive),以人类可读的方式打印参数。
  • ~s:语法指令(Syntactic directive),以 Lisp 读取的方式打印参数(例如,字符串带引号)。
  • ~d:以十进制打印整数。
  • ~%:打印换行符。
  • ~~:打印字面量波浪号 ~ 字符。

此示例创建一个格式化字符串,其中包含一个数字和一个字符串参数。

;; 使用 `format` 并以 `nil` 为目标来创建字符串。
(let ((user-name "Alex")
(items-count 42))
(format nil "User ~a has ~d items in the cart." user-name items-count))
"User Alex has 42 items in the cart."

with-output-to-string 宏是最高效地以程序化方式从许多小片段构建字符串的方法。它创建了一个字符串流(string stream),并捕获所有导向其的输出。这避免了创建许多中间字符串对象,这在循环中可能效率低下。

在此,我们通过迭代项目列表来构建字符串。

;; 定义要组装的部件列表。
(defvar *parts* '("chassis" "engine" "wheels"))
;; 使用宏构建最终字符串。
(with-output-to-string (s) ; `s` 是流变量
(write-string "Assembly report:~%" s)
(dolist (part *parts*)
(format s "- Installing ~a...~%" part))
(write-string "Assembly complete." s))
"Assembly report:
- Installing chassis...
- Installing engine...
- Installing wheels...
Assembly complete."
  • 使用 concatenate 进行少量已知字符串的简单、一次性拼接。它清晰直接。
  • 使用 format 每当你需要将数据嵌入模板字符串时。它功能强大、可读性高,是格式化文本的惯用选择。
  • 使用 with-output-to-string 当你分段构建字符串时,尤其是在循环或复杂条件逻辑内部。它为增量字符串构建提供了最佳性能。