Formatting格式化 指的是在一个常量字符串的不同位置代入计算所得的值,从而构造出一个新字符串。这个常量字符串控制着其他值的打印方式和显示位置,它被称为 format string格式字符串。
格式化常用于生成需要显示的消息。实际上,message 和 error 函数也提供了本节所描述的格式化功能;它们与 format-message 的区别仅在于对格式化结果的使用方式不同。
该函数返回一个与 string 等效的字符串,其中所有 format specifications格式说明符 都会被替换为对应 objects 的编码形式。参数 objects 是待格式化的计算结果值。
string 中除格式说明符外的其他字符,会直接复制到输出结果中(包括其文本属性,如果有的话)。格式说明符本身的所有文本属性,都会复制到参数 objects 生成的字符串表示上。
输出字符串不一定是新分配的。例如,若 x 是字符串 "foo",表达式 (eq x (format x)) 和 (eq x (format "%s" x)) 都可能返回 t。
该函数的行为与 format 类似,区别在于它还会根据 text-quoting-style 的值,转换字符串 string 中的重音符 (`) 和撇号 (')。
通常,格式字符串中的重音符和撇号会转换为配对的弯引号,例如 "Missing `%s'" 可能会生成 "Missing ‘foo’"。有关如何影响或禁止此转换的说明,see Text Quoting Style。
格式说明符是以 ‘%’ 开头的字符序列。因此,如果字符串 string 中包含 ‘%d’,format 函数会将其替换为待格式化值(参数 objects 中的一个)的打印形式。例如:
(format "The value of fill-column is %d." fill-column)
⇒ "The value of fill-column is 72."
由于 format 会将 ‘%’ 字符解析为格式说明符,因此 切勿 将任意字符串作为第一个参数传入。当该字符串由某些 Lisp 代码生成时,这一点尤为重要。除非确定字符串中绝不会包含任何 ‘%’ 字符,否则应将下文所述的 ‘"%s"’ 作为第一个参数,待传入的字符串作为第二个参数,示例如下:
(format "%s" arbitrary-string)
某些格式说明符要求值为特定类型。如果传入的值不符合要求,会触发错误。
以下是有效的格式说明符对照表:
将说明符替换为对象的无引号打印表示形式(即使用 princ 而非 prin1 — see 输出函数)。因此,字符串仅以其内容表示,不带 ‘"’ 字符;符号也不会显示 ‘\’ 字符。
若对象是字符串,其文本属性会复制到输出结果中。‘%s’ 本身的文本属性也会被复制,但对象的文本属性优先级更高。
将说明符替换为对象的带引号打印表示形式(即使用 prin1 — see 输出函数)。因此,字符串会被 ‘"’ 字符包裹,特殊字符前会按需显示 ‘\’ 字符。
将说明符替换为整数的八进制表示形式。负整数的格式化方式依赖于具体平台。该对象也可以是浮点数,此时会被格式化为整数(舍弃小数部分)。
将说明符替换为有符号整数的十进制表示形式。该对象也可以是浮点数,此时会被格式化为整数(舍弃小数部分)。
将说明符替换为整数的十六进制表示形式。负整数的格式化方式依赖于具体平台。‘%x’ 使用小写字母,‘%X’ 使用大写字母。该对象也可以是浮点数,此时会被格式化为整数(舍弃小数部分)。
将说明符替换为对应值的字符。
将说明符替换为浮点数的指数表示形式。
将说明符替换为浮点数的小数点表示形式。
将说明符替换为浮点数的表示形式(指数表示或小数点表示二选一)。若指数小于 −4 或大于等于精度值(默认值:6),则使用指数表示。默认情况下,结果的小数部分会去除末尾的零,且仅当小数点后有数字时才显示小数点。
将说明符替换为单个 ‘%’。该格式说明符较为特殊:仅支持 ‘%%’ 这一种形式,且不使用任何值。例如,(format "%% %d" 30) 会返回 "% 30"。
任何其他格式字符都会触发 ‘Invalid format operation无效的格式操作’ 错误。
以下是若干示例(假设使用默认的 text-quoting-style 设置):
(format "The octal value of %d is %o,
and the hex value is %x." 18 18 18)
⇒ "The octal value of 18 is 22,
and the hex value is 12."
(format-message
"The name of this buffer is ‘%s’." (buffer-name))
⇒ "The name of this buffer is ‘strings.texi’."
(format-message
"The buffer object prints as `%s'." (current-buffer))
⇒ "The buffer object prints as ‘strings.texi’."
默认情况下,格式说明符按顺序对应 objects 中的各个值。因此,字符串 string 中的第一个格式说明符使用第一个值,第二个格式说明符使用第二个值,依此类推。多余的格式说明符(无对应值的说明符)会触发错误,而多余的待格式化值则会被忽略。
格式说明符可包含 field number字段编号:即在起始的 ‘%’ 后紧跟一个十进制数字,再加上一个字面美元符号 ‘$’。此字段编号会让格式说明符使用指定编号的参数,而非下一个参数。字段编号从 1 开始。一个格式字符串中只能包含编号格式说明符或无编号格式说明符二者之一,例外情况是 ‘%%’ 可与编号格式说明符混用。
(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
⇒ "y, z, %, x"
在 ‘%’ 和 field number字段编号(如有)之后,可添加特定的 flag characters标志字符。
标志 ‘+’ 会在非负数前添加一个加号,使其始终带有符号。 将空格作为标志时,会在非负数前插入一个空格。(否则,非负数会直接以第一位数字开头。) 这些标志用于保证非负数与负数占用相同的列宽。它们仅对 ‘%d’、‘%e’、‘%f’、‘%g’ 生效,在其他格式中会被忽略;如果同时使用这两个标志,‘+’ 优先。
标志 ‘#’ 指定一种备用输出形式,具体行为取决于所用格式:
标志 ‘0’ 会确保填充字符为 ‘0’,而不是空格。该标志对 ‘%s’、‘%S’、‘%c’ 等非数值说明符无效(这些说明符虽接受 ‘0’ 标志,但仍用 空格 填充)。
标志 ‘-’,若指定了宽度,填充字符会添加在右侧而非左侧。若 ‘-’ 和 ‘0’ 同时出现,‘0’ 标志会被忽略。
(format "%06d is padded on the left with zeros" 123)
⇒ "000123 is padded on the left with zeros"
(format "'%-6d' is padded on the right" 123)
⇒ "'123 ' is padded on the right"
(format "The word '%-7s' actually has %d letters in it."
"foo" (length "foo"))
⇒ "The word 'foo ' actually has 3 letters in it."
格式说明符可指定 width宽度,宽度是一个十进制数字,位于 field number字段编号 和 flag characters标志字符 之后。如果对象的打印表示形式长度小于该宽度, format 会填充字符将其补齐。宽度引入的填充字符默认是左侧的空格:
(format "%5d is padded on the left with spaces" 123)
⇒ " 123 is padded on the left with spaces"
若宽度过小,format 不会截断对象的打印表示形式。因此,可通过宽度指定列之间的最小间距,且无需担心信息丢失。以下两个示例中,‘%7s’ 指定最小宽度为 7:第一个示例中,替换 ‘%7s’ 的字符串仅 3 个字符,需填充 4 个空格;第二个示例中,字符串 "specification" 长度为 13,但不会被截断。
(format "The word '%7s' has %d letters in it."
"foo" (length "foo"))
⇒ "The word ' foo' has 3 letters in it."
(format "The word '%7s' has %d letters in it."
"specification" (length "specification"))
⇒ "The word 'specification' has 13 letters in it."
所有格式说明符均可在 field number字段编号、flag标志和 width宽度(如果存在)之后,都允许使用一个可选的 precision精度。精度由一个小数点 ‘.’ 后跟数字串组成。
对于浮点型格式说明符(‘%e’ 和 ‘%f’ ),精度指定小数点后显示的位数;若精度为 0,小数点也会省略。
对于 ‘%g’,精度指定显示多少位有效数字(有效数字包括小数点前第一位和小数点后所有数字);若精度为 0 或未指定,则按 1 处理。
对于 ‘%s’ 和 ‘%S’,精度将字符串截断至指定长度,因此 ‘%.3s’ 仅显示 object对象 表示形式的前 3 个字符。
对于其他说明符:精度的效果与本地 printf 系列库函数的行为一致。
如果你打算稍后在格式化后的字符串上使用 read 函数来取回格式化值的副本,请使用能让 read 重建该值的格式说明符。
要以这种可还原的方式格式化数字,你可以w使用 ‘%s’ 和 ‘%S’;仅格式化整数时,你还可使用 ‘%d’;仅格式化非负整数时,你还可以使用 ‘#x%x’ 和 ‘#o%o’。
其他格式可能存在问题;例如,‘%d’ 和 ‘%g’ 可能会错误处理 NaN 并丢失精度与类型信息,而 ‘#x%x’ 和 ‘#o%o’ 可能会错误处理负整数)。See 输入函数。
本节描述的函数仅支持固定的一组格式说明符。下一节将介绍函数 format-spec,该函数可支持自定义格式说明符,例如 ‘%a’ 或 ‘%z’。