文字列を結合する - lisp-cookbook-ja/common-lisp GitHub Wiki

文字列 シーケンス

複数の文字列を結合する

文字列シーケンスなのでconcatenateで結合できます。また、formatで文字列に出力しても良いでしょう。

;; concatenateはシーケンスをつなげることができる
(concatenate 'string "foo" "bar")       ;=> "foobar"

;; formatの文字列に出力する機能を利用する
(format nil "~A~A" "foo" "bar")         ;=> "foobar"

concatenateもformatも、もとの文字列は変更しません。

;; concatenateを評価してもs1とs2には影響はない
(let ((s1 "foo")
      (s2 "bar"))
  (list (concatenate 'string s1 s2) s1 s2))
;=> ("foobar" "foo" "bar")

文字列ストリームを使うこともできます。

;; with-output-to-stringはストリームに出力した内容を文字列にして返す
(with-output-to-string (out)
  (format out "foo")
  (format out "bar"))
;=> "foobar"

文字列のリストを結合する

文字列のリストを結合するときはformatを使うと便利です。

;; formatでリストの要素を繰り返し処理する
(format nil "~{~A~}" '("foo" "bar"))
;=> "foobar"

concatenateにapplyを使う方法もあります。

;; applyの引数は柔軟に書ける
(apply #'concatenate 'string '("foo" "bar"))
;=> "foobar"

文字列ストリームを使うとより柔軟に結合できます。

;; ストリームに出力していけばいいので単純で自由度が高い
(with-output-to-string (s)
  (dolist (e '("foo" "bar"))
    (princ e s)))
;=> "foobar"

途中で一時的な文字列を作るため効率は良くありませんが、reduceでつなげていくこともできます。

;; reduceで畳み込む
(reduce (lambda (r x) (concatenate 'string r x))
        '("foo" "bar"))
;=> "foobar"