格式规范

一些 Ruby 核心类具有实例方法 printfsprintf

每个方法都接受

每个方法都会打印或返回一个字符串,该字符串是通过将 format_string 中嵌入的每个格式规范替换为 arguments 中对应参数的字符串形式而生成的。

一个简单的例子

sprintf('Name: %s; value: %d', 'Foo', 0) # => "Name: Foo; value: 0"

格式规范具有以下形式

%[flags][width][.precision]type

它包含

除了前导百分号字符外,唯一必需的部分是类型说明符,因此我们从它开始。

类型说明符

本节简要解释了每个类型说明符。链接指向详细信息和示例。

整数类型说明符

浮点类型说明符

其他类型说明符

标志

标志的效果在不同类型说明符之间可能会有很大差异。这些说明是通用的。参见 类型特定的详细信息

多个标志可以与单个类型说明符一起使用;顺序无关紧要。

' ' 标志

在非负数之前插入一个空格

sprintf('%d', 10)  # => "10"
sprintf('% d', 10) # => " 10"

对于负值插入一个减号

sprintf('%d', -10)  # => "-10"
sprintf('% d', -10) # => "-10"

'#' 标志

使用备用格式;在不同类型之间有所不同

sprintf('%x', 100)  # => "64"
sprintf('%#x', 100) # => "0x64"

'+' 标志

为非负数添加一个前导加号

sprintf('%x', 100)  # => "64"
sprintf('%+x', 100) # => "+64"

'-' 标志

在字段中左对齐值

sprintf('%6d', 100)  # => "   100"
sprintf('%-6d', 100) # => "100   "

'0' 标志

用零而不是空格左填充

sprintf('%6d', 100)  # => "   100"
sprintf('%06d', 100) # => "000100"

'*' 标志

使用下一个参数作为字段宽度

sprintf('%d', 20, 14)  # => "20"
sprintf('%*d', 20, 14) # => "                  14"

'n$' 标志

将(从 1 开始的)第 n 个参数格式化为该字段

sprintf("%s %s", 'world', 'hello')     # => "world hello"
sprintf("%2$s %1$s", 'world', 'hello') # => "hello world"

宽度说明符

通常,宽度说明符确定格式化字段的最小宽度(以字符为单位)

sprintf('%10d', 100)  # => "       100"

# Left-justify if negative.
sprintf('%-10d', 100) # => "100       "

# Ignore if too small.
sprintf('%1d', 100)   # => "100"

精度说明符

精度说明符是一个小数点,后面跟着零个或多个十进制数字。

对于整数类型说明符,精度指定要写入的最小位数。如果精度小于整数,则结果将用前导零填充。如果整数大于精度,则结果不会修改或截断

sprintf('%.3d', 1)    # => "001"
sprintf('%.3d', 1000) # => "1000"

# If the precision is 0 and the value is 0, nothing is written
sprintf('%.d', 0)  # => ""
sprintf('%.0d', 0) # => ""

对于 a/Ae/Ef/F 说明符,精度指定要写入小数点后的位数

sprintf('%.2f', 3.14159)  # => "3.14"
sprintf('%.10f', 3.14159) # => "3.1415900000"

# With no precision specifier, defaults to 6-digit precision.
sprintf('%f', 3.14159)    # => "3.141590"

对于 g/G 说明符,精度指定要写入的有效位数

sprintf('%.2g', 123.45)  # => "1.2e+02"
sprintf('%.3g', 123.45)  # => "123"
sprintf('%.10g', 123.45) # =>  "123.45"

# With no precision specifier, defaults to 6 significant digits.
sprintf('%g', 123.456789) # => "123.457"

对于 sp 说明符,精度指定要写入的字符数

sprintf('%s', Time.now)    # => "2022-05-04 11:59:16 -0400"
sprintf('%.10s', Time.now) # => "2022-05-04"

类型说明符详细信息和示例

说明符 aA

argument 格式化为十六进制浮点数

sprintf('%a', 3.14159)   # => "0x1.921f9f01b866ep+1"
sprintf('%a', -3.14159)  # => "-0x1.921f9f01b866ep+1"
sprintf('%a', 4096)      # => "0x1p+12"
sprintf('%a', -4096)     # => "-0x1p+12"

# Capital 'A' means that alphabetical characters are printed in upper case.
sprintf('%A', 4096)      # => "0X1P+12"
sprintf('%A', -4096)     # => "-0X1P+12"

说明符 bB

两个说明符 bB 的行为相同,除非使用标志 '#'+。

argument 格式化为二进制整数

sprintf('%b', 1)  # => "1"
sprintf('%b', 4)  # => "100"

# Prefix '..' for negative value.
sprintf('%b', -4) # => "..100"

# Alternate format.
sprintf('%#b', 4)  # => "0b100"
sprintf('%#B', 4)  # => "0B100"

说明符 c

argument 格式化为单个字符

sprintf('%c', 'A') # => "A"
sprintf('%c', 65)  # => "A"

说明符 d

argument 格式化为十进制整数

sprintf('%d', 100)  # => "100"
sprintf('%d', -100) # => "-100"

标志 '#' 不适用。

说明符 eE

argument 格式化为 科学记数法

sprintf('%e', 3.14159)  # => "3.141590e+00"
sprintf('%E', -3.14159) # => "-3.141590E+00"

说明符 f

argument 格式化为浮点数

sprintf('%f', 3.14159)  # => "3.141590"
sprintf('%f', -3.14159) # => "-3.141590"

标志 '#' 不适用。

说明符 gG

如果指数小于 -4 或大于或等于精度,则使用指数形式(e/E 说明符)格式化 argument。否则使用浮点形式(f 说明符)格式化 argument

sprintf('%g', 100)  # => "100"
sprintf('%g', 100.0)  # => "100"
sprintf('%g', 3.14159)  # => "3.14159"
sprintf('%g', 100000000000)  # => "1e+11"
sprintf('%g', 0.000000000001)  # => "1e-12"

# Capital 'G' means use capital 'E'.
sprintf('%G', 100000000000)  # => "1E+11"
sprintf('%G', 0.000000000001)  # => "1E-12"

# Alternate format.
sprintf('%#g', 100000000000)  # => "1.00000e+11"
sprintf('%#g', 0.000000000001)  # => "1.00000e-12"
sprintf('%#G', 100000000000)  # => "1.00000E+11"
sprintf('%#G', 0.000000000001)  # => "1.00000E-12"

说明符 o

argument 格式化为八进制整数。如果 argument 为负数,它将被格式化为以 ..7 为前缀的二进制补码

sprintf('%o', 16)   # => "20"

# Prefix '..7' for negative value.
sprintf('%o', -16)  # => "..760"

# Prefix zero for alternate format if positive.
sprintf('%#o', 16)  # => "020"
sprintf('%#o', -16) # => "..760"

说明符 p

通过 argument.inspectargument 格式化为字符串

t = Time.now
sprintf('%p', t)   # => "2022-05-01 13:42:07.1645683 -0500"

说明符 s

通过 argument.to_sargument 格式化为字符串

t = Time.now
sprintf('%s', t) # => "2022-05-01 13:42:07 -0500"

标志 '#' 不适用。

说明符 xX

argument 格式化为十六进制整数。如果 argument 为负数,它将被格式化为以 ..f 为前缀的二进制补码

sprintf('%x', 100)   # => "64"

# Prefix '..f' for negative value.
sprintf('%x', -100)  # => "..f9c"

# Use alternate format.
sprintf('%#x', 100)  # => "0x64"

# Alternate format for negative value.
sprintf('%#x', -100) # => "0x..f9c"

说明符 %

argument ('%') 格式化为单个百分号字符

sprintf('%d %%', 100) # => "100 %"

标志不适用。

按名称引用

对于更复杂的格式,Ruby 支持按名称引用。%<name>s 样式使用格式样式,但 %{name} 样式不使用。

示例

sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 }) # => 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })                      # => "1f"