我想转换("USERID=XYZ" "USERPWD=123")
为"USERID=XYZ&USERPWD=123"
.我试过了
(apply #'concatenate 'string '("USERID=XYZ" "USERPWD=123"))
Run Code Online (Sandbox Code Playgroud)
将返回""USERID=XYZUSERPWD=123"
.
但我不知道如何插入'&'?以下功能有效但似乎有点复杂.
(defun join (list &optional (delim "&"))
(with-output-to-string (s)
(when list
(format s "~A" (first list))
(dolist (element (rest list))
(format s "~A~A" delim element)))))
Run Code Online (Sandbox Code Playgroud)
Pau*_*han 44
使用FORMAT.
~{
并且~}
表示迭代,~A
表示美学印刷,并且~^
(文档中的称为Tilde Circumflex)表示仅在其后的某些内容打印时.
* (format nil "~{~A~^, ~}" '( 1 2 3 4 ))
"1, 2, 3, 4"
*
Run Code Online (Sandbox Code Playgroud)
小智 6
Melpa托管包s(“失传已久的 Emacs 字符串操作库”),它提供了许多简单的字符串实用程序,包括字符串连接器:
(require 's)
(s-join ", " (list "a" "b" "c"))
"a, b, c"
Run Code Online (Sandbox Code Playgroud)
就其价值而言,它在底层使用了几个 lisp 函数fns.c
,即mapconcat
和identity
:
(mapconcat 'identity (list "a" "b" "c") ", ")
"a, b, c"
Run Code Online (Sandbox Code Playgroud)
此解决方案允许我们使用FORMAT
生成字符串并具有可变分隔符.目的不是为每个函数调用一个新的格式字符串.一个好的Common Lisp编译器也可能想要编译给定的固定格式字符串 - 在运行时构造格式字符串时会失败.看宏formatter
.
(defun %d (stream &rest args)
"internal function, writing the dynamic value of the variable
DELIM to the output STREAM. To be called from inside JOIN."
(declare (ignore args)
(special delim))
(princ delim stream))
(defun join (list delim)
"creates a string, with the elements of list printed and each
element separated by DELIM"
(declare (special delim))
(format nil "~{~a~^~/%d/~:*~}" list))
Run Code Online (Sandbox Code Playgroud)
说明:
"~{ iteration start
~a print element
~^ exit iteration if no more elements
~/%d/ call function %d with one element
~:* move one element backwards
~}" end of iteration command
Run Code Online (Sandbox Code Playgroud)
%d
只是一个"内部"功能,不应该在外面调用join
.作为标记,它有%
前缀.
~/foo/
是一种从格式字符串调用函数 的方法.foo
变量delim
被声明为特殊的,因此转换到%d
函数中的分隔符可以有一个值.因为我们不能让Lisp 使用delimiter参数调用%d
函数FORMAT
,所以我们需要从其他地方获取它 - 这里是join
函数引入的动态绑定.
该函数的唯一目的%d
是编写分隔符 - 它忽略传递的参数format
- 它只使用stream
参数.