4.7 字符串格式化

格式化指,通过对常量字符串进行替换,从而计算并构造出新字符串的操作。这些常量字符控制如何进行计算,以及如何显示这些字符串;这种操作称为格式化字符串。

格式化字符串通常在调试,记录时非常有用。实际上,函数 message 和 error 同样提供本节介绍的字符串格式化操作;它们和 format-message 的不同点仅仅在于它们如何使用结果。

函数: format string &rest objects

该函数使用 objects 替换 string 种特定的字符,生成并返回另一个字符串。参数 objects 即是参与计算的值。

string 中除去特定字符外的所有字符都会原样输出,包括它们的文本属性。objects 中的文本属性也会被拷贝并按照原样输出。

生成的字符串很可能不是完全新创建的。举个例子,若 x 是字符串 "foo",那么表达式 (eq x (format x)) 和 表达式 (eq x (format "%s" x)) 很可能都为 t。

函数: format-message string &rest objects

该函数和 format 非常相似,不同点在于该函数同样提供重音和撇号的转换。

通常重音和撇号会对应到斜引号,举个例子,"Missing `%s‘" 会生成 "Missing ’foo‘"。详情查阅 文本引用风格,以了解如何影响这类转换。

通常,格式化标记是一个以 '%' 开头的字符序列。当遇到 '%d' 时,函数 format 会将其替换为 参数 objects 中某个参数对应的打印表示。举个例子:

(format "The value of fill-column is %d." fill-column)
     ⇒ "The value of fill-column is 72."

format 将字符 '%' 解释为格式化标记,因此该函数的第一个参数需要和后续的参数匹配。这里有一个例子:

(format "%s" arbitrary-string)

每个特定的格式化标记都要对应着特定类型的数据。如果你提供的值和格式化标记不对应,则会抛出错误。

这里有一个格式化标记集合:

'%s'

使用对象的打印表示替换该标记(使用princ 而非 prin1 输出函数)。中间不会出现 '"'字符,且符号出现的地方也不会有 '\' 字符。

若对象是字符串,那么还会将文本属性也复制到输出中。'%s'本身的文本属性也会被拷贝,但优先拷贝对象的属性

'%S'

使用对象的打印表示替换该标记(使用 print1 输出函数)。中间会出现引号。因此,字符串会被 '"' 包围起来,且'\' 会出现在必要的地方。

'%o'

使用对象的八进制表示来替换标记。若传入值为负数,那么输出结果会很依赖具体平台。传入值同样可以为浮点数,在传入后,会将其小数部分略去。

'%d'

使用对象的十进制表示来替换标记。传入值同样可以为浮点数,传入后,会将其小数部分略去。

'%x'

'%X'

使用对象的十六进制来替换标记。传入值为负数时,输出结果会很依赖具体平台。其中 '%x' 使用小写字母,'%X' 使用大写字母。传入值同样可以为浮点数,传入后会将小数部分略去。

'%c'

使用字符替换标记。

'%e'

使用浮点数指数记法来替换标记。

'%f'

使用浮点数小数表示来替换标记。

'%g'

使用指数记法或小数表示来替换标记。(TODO)

'%%'

使用 '%' 替代标记。该标记不使用值。例如,(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’."

最后更新于