首页 > 解决方案 > 支持的 Swift 字符串格式说明符有哪些?

问题描述

在 Swift 中,我可以使用格式说明符格式化字符串:

// This will return "0.120"
String(format: "%.03f", 0.12)

但是官方文档没有提供有关支持的格式说明符或如何构建类似于以下模板的任何信息或链接"%.03f"https ://developer.apple.com/documentation/swift/string/3126742-init

它只说:

返回使用给定格式字符串作为模板初始化的 String 对象,剩余的参数值将被替换到该模板中。

标签: swiftstringstring-formatting

解决方案


Swift 中用于格式化的格式说明符String与 Objective-CNSString格式中的格式说明符相同,其本身与格式说明符相同,CFString并且深埋在 Apple 文档的档案中(两个页面的内容相同,都来自 2002 年或更早):

但是这个文档页面本身是不完整的,例如flags精度说明符和宽度说明符没有被提及。实际上,它声称遵循IEEE printf 规范(第 6 期,2004 版),本身与 ISO C 标准保持一致。因此,这些说明符应该与我们在 C中的说明符相同,只是为 Objective-C 对象printf添加了说明符,并添加了记录不充分的, ,说明符和长度修饰符。%@%D%U%Oq


说明符

每个转换规范都由“%”字符或字符序列“%n$”引入。

n是参数的索引,如:

String(format: "%2$@ %1$@", "world", "Hello")

格式说明符

%@ Objective-C 对象,打印为 descriptionWithLocale 返回的字符串:如果可用,否则为描述。

实际上,您也可以使用一些 Swift 类型,但它们必须在标准库中定义才能符合 CVarArg 协议,并且我相信它们需要支持与 Objective-C 对象的桥接:https://developer.apple。 com/documentation/foundation/object_runtime/classes_bridged_to_swift_standard_library_value_types

String(format: "%@", ["Hello", "world"])

%% '%' 特点。

String(format: "100%% %@", true.description)

%d, %i 有符号 32 位整数 (int)。

String(format: "from %d to %d", Int32.min, Int32.max)

%u, %U, %D 无符号 32 位整数 (unsigned int)。

String(format: "from %u to %u", UInt32.min, UInt32.max)

%x 无符号 32 位整数 (unsigned int),使用数字 0–9 和小写 a–f 以十六进制打印。

String(format: "from %x to %x", UInt32.min, UInt32.max)

%X 无符号 32 位整数 (unsigned int),使用数字 0–9 和大写 A–F 以十六进制形式打印。

String(format: "from %X to %X", UInt32.min, UInt32.max)

%o, %O 无符号 32 位整数 (unsigned int),以八进制打印。

String(format: "from %o to %o", UInt32.min, UInt32.max)

%f 64 位浮点数(双精度),以十进制表示法打印。产生“inf”、“infinity”或“nan”。

String(format: "from %f to %f", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%F 64 位浮点数(双精度),以十进制表示法打印。产生“INF”、“INFINITY”或“NAN”。

String(format: "from %F to %F", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%e 64 位浮点数(双精度),以科学计数法打印,使用小写 e 引入指数。

String(format: "from %e to %e", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%E 64 位浮点数(双精度),以科学计数法打印,使用大写 E 引入指数。

String(format: "from %E to %E", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%g 64 位浮点数(双精度),如果指数小于 –4 或大于或等于精度,则以 %e 的样式打印,否则以 %f 的样式打印。

String(format: "from %g to %g", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%G 64 位浮点数(双精度),如果指数小于 –4 或大于或等于精度,则以 %E 的样式打印,否则以 %f 的样式打印。

String(format: "from %G to %G", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%c 8 位无符号字符(无符号字符)。

String(format: "from %c to %c", "a".utf8.first!, "z".utf8.first!)

%C 16 位 UTF-16 代码单元(unichar)。

String(format: "from %C to %C", "爱".utf16.first!, "终".utf16.first!)

%s 以 Null 结尾的 8 位无符号字符数组。

"Hello world".withCString {
    String(format: "%s", $0)
}

%S 以 Null 结尾的 16 位 UTF-16 代码单元数组。

"Hello world".withCString(encodedAs: UTF16.self) {
    String(format: "%S", $0)
}

%p 空指针 (void *),以十六进制打印,数字 0-9 和小写 a-f,前导 0x。

var hello = "world"
withUnsafePointer(to: &hello) {
    String(format: "%p", $0)
}

%n 参数应该是一个指向整数的指针,其中写入了到目前为止通过调用 fprintf() 函数之一写入输出的字节数。

Swift 4+中n似乎不支持格式说明符

%a 64 位浮点数(双精度),以科学记数法打印,前导 0x 和小数点前一个十六进制数字,使用小写 p 引入指数。

String(format: "from %a to %a", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

%A 64 位浮点数(双精度),以科学计数法打印,前导 0X 和小数点前一个十六进制数字,使用大写 P 引入指数。

String(format: "from %A to %A", Double.leastNonzeroMagnitude, Double.greatestFiniteMagnitude)

标志

' 十进制转换结果的整数部分(%i、%d、%u、%f、%F、%g 或 %G)应使用千位分组字符进行格式化。对于其他转换,行为未定义。使用非货币分组字符。

'Swift 4+ 中似乎不支持该标志

- 转换结果应在字段内左对齐。如果未指定此标志,则转换为右对齐。

String(format: "from %-12f to %-12d.", Double.leastNonzeroMagnitude, Int32.max)

+ 带符号转换的结果应始终以符号(“+”或“-”)开头。如果未指定此标志,则仅在转换负值时转换应以符号开始。

String(format: "from %+f to %+d", Double.leastNonzeroMagnitude, Int32.max)

<space> 如果有符号转换的第一个字符不是符号,或者如果有符号转换没有字符,则应在结果前加上 <space>。这意味着如果 <space> 和 '+' 标志都出现,则应忽略 <space> 标志。

String(format: "from % d to % d.", Int32.min, Int32.max)

# 指定将值转换为另一种形式。对于 o 转换,它会增加精度(如有必要)以强制结果的第一位为零。对于 x 或 X 转换说明符,非零结果应以 0x(或 0X)为前缀。对于 a、A、e、E、f、F、g 和 G 转换说明符,结果应始终包含一个基数字符,即使基数字符后面没有数字。如果没有这个标志,基数字符仅在数字后面出现时才会出现在这些转换的结果中。对于 g 和 G 转换说明符,不应像通常那样从结果中删除尾随零。对于其他转换说明符,行为未定义。

String(format: "from %#a to %#x.", Double.leastNonzeroMagnitude, UInt32.max)

0 对于 d、i、o、u、x、X、a、A、e、E、f、F、g 和 G 转换说明符,前导零(在符号或基数的任何指示之后)用于填充场宽;不执行空格填充。如果“0”和“-”标志都出现,则“0”标志被忽略。对于 d、i、o、u、x 和 X 转换说明符,如果指定了精度,则忽略“0”标志。如果 '0' 和 '" 标志都出现,则在零填充之前插入分组字符。对于其他转换,行为未定义。

String(format: "from %012f to %012d.", Double.leastNonzeroMagnitude, Int32.max)

宽度修饰符

如果转换后的值的字节数小于字段宽度,则默认在左侧填充空格;如果将左调整标志('-')赋予字段宽度,则应在右侧填充。字段宽度采用星号 ('*') 或十进制整数的形式。

String(format: "from %12f to %*d.", Double.leastNonzeroMagnitude, 12, Int32.max)

精密修饰符

一个可选精度,给出 d、i、o、u、x 和 X 转换说明符出现的最小位数;在 a、A、e、E、f 和 F 转换说明符的基数字符之后出现的位数;g 和 G 转换说明符的最大有效位数;或从 s 和 S 转换说明符中的字符串打印的最大字节数。精度采用句点 ('.') 后跟星号 ('*') 或可选的十进制数字字符串的形式,其中空数字字符串被视为零。如果精度与任何其他转换说明符一起出现,则行为未定义。

String(format: "from %.12f to %.*d.", Double.leastNonzeroMagnitude, 12, Int32.max)

长度修饰符

h 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于短或无符号短参数。

String(format: "from %hd to %hu", CShort.min, CUnsignedShort.max)

hh 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于有符号字符或无符号字符参数。

String(format: "from %hhd to %hhu", CChar.min, CUnsignedChar.max)

l 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于 long 或 unsigned long 参数。

String(format: "from %ld to %lu", CLong.min, CUnsignedLong.max)

ll、q 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于 long long 或 unsigned long long 参数。

String(format: "from %lld to %llu", CLongLong.min, CUnsignedLongLong.max)

L 长度修饰符,指定后面的 a、A、e、E、f、F、g 或 G 转换说明符适用于 long double 参数。

我无法format在 Swift 4+中传递 CLongDouble 参数

z 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于 size_t。

String(format: "from %zd to %zu", size_t.min, size_t.max)

t 长度修饰符,指定后面的 d、o、u、x 或 X 转换说明符适用于 ptrdiff_t。

String(format: "from %td to %tu", ptrdiff_t.min, ptrdiff_t.max)

j 指定以下 d、o、u、x 或 X 转换说明符的长度修饰符适用于 intmax_t 或 uintmax_t 参数。

String(format: "from %jd to %ju", intmax_t.min, uintmax_t.max)

推荐阅读