支持哪些 Swift 字符串格式说明符? [英] What are the supported Swift String format specifiers?

查看:32
本文介绍了支持哪些 Swift 字符串格式说明符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

//这将返回0.120"字符串(格式:%.03f",0.12)

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

它只说:

<块引用>

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

解决方案

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

但是这个文档页面本身并不完整,例如没有提到 flagsprecision 说明符和 width 说明符.实际上,它声称遵循 IEEE printf 规范(第 6 期,2004 版),本身符合 ISO C 标准.所以这些说明符应该与我们在 C printf 中的相同,为 Objective-C 对象添加了 %@ 说明符,并添加了记录不佳的 %D%U%O 说明符和 q 长度修饰符.

<小时>

说明符

<块引用>

每个转换规范都由%"字符或字符序列%n$"引入.

n 是参数的索引,如:

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

格式说明符

<块引用>

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

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

String(格式: "%@", ["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 位整数(无符号整数).

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 位浮点数 (double),以十进制表示法打印.产生inf"、infinity"或nan".

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

<块引用>

%F   64 位浮点数 (double),以十进制表示法打印.产生INF"、INFINITY"或NAN".

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

<块引用>

%e  64 位浮点数 (double),以科学记数法打印,使用小写 e 来引入指数.

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

<块引用>

%E  64 位浮点数 (double),以科学记数法打印,使用大写 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 位浮点数 (double),如果指数小于 –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   以空结尾的 8 位无符号字符数组.

"Hello world".withCString {字符串(格式:%s",$0)}

<块引用>

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

"Hello world".withCString(encodedAs: UTF16.self) {字符串(格式:%S",$0)}

<块引用>

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

var hello = "world"withUnsafePointer(to: &hello) {字符串(格式:%p",$0)}

<块引用>

%n   参数应是一个指向整数的指针,通过调用 fprintf() 函数之一将写入到输出的字节数写入该整数.

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

<块引用>

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

>

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

<块引用>

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

>

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

标志

<块引用>

'   a结果的整数部分十进制转换(%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 转换说明符,如果 a指定精度,则忽略 '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长论.

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双重论证.

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

<块引用>

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)

In Swift, I can format a String with format specifiers:

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

But the official documentation is not giving any information or link regarding the supported format specifiers or how to build a template similar to "%.03f": https://developer.apple.com/documentation/swift/string/3126742-init

It only says:

Returns a String object initialized by using a given format string as a template into which the remaining argument values are substituted.

解决方案

The format specifiers for String formatting in Swift are the same as those in Objective-C NSString format, itself identical to those for CFString format and are buried deep in the archives of Apple Documentation (same content for both pages, both originally from year 2002 or older):

But this documentation page itself is incomplete, for instance the flags, the precision specifiers and the width specifiers aren't mentioned. Actually, it claims to follow IEEE printf specifications (Issue 6, 2004 Edition), itself aligned with the ISO C standard. So those specifiers should be identical to what we have with C printf, with the addition of the %@ specifier for Objective-C objects, and the addition of the poorly documented %D, %U, %O specifiers and q length modifier.


Specifiers

Each conversion specification is introduced by the '%' character or by the character sequence "%n$".

n is the index of the parameter, like in:

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

Format Specifiers

%@    Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise.

Actually, you may also use some Swift types, but they must be defined inside the standard library in order to conform to the CVarArg protocol, and I believe they need to support bridging to Objective-C objects: https://developer.apple.com/documentation/foundation/object_runtime/classes_bridged_to_swift_standard_library_value_types.

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

%%    '%' character.

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

%d, %i    Signed 32-bit integer (int).

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

%u, %U, %D    Unsigned 32-bit integer (unsigned int).

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

%x    Unsigned 32-bit integer (unsigned int), printed in hexadecimal using the digits 0–9 and lowercase a–f.

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

%X    Unsigned 32-bit integer (unsigned int), printed in hexadecimal using the digits 0–9 and uppercase A–F.

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

%o, %O    Unsigned 32-bit integer (unsigned int), printed in octal.

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

%f    64-bit floating-point number (double), printed in decimal notation. Produces "inf", "infinity", or "nan".

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

%F    64-bit floating-point number (double), printed in decimal notation. Produces "INF", "INFINITY", or "NAN".

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

%e    64-bit floating-point number (double), printed in scientific notation using a lowercase e to introduce the exponent.

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

%E    64-bit floating-point number (double), printed in scientific notation using an uppercase E to introduce the exponent.

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

%g    64-bit floating-point number (double), printed in the style of %e if the exponent is less than –4 or greater than or equal to the precision, in the style of %f otherwise.

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

%G    64-bit floating-point number (double), printed in the style of %E if the exponent is less than –4 or greater than or equal to the precision, in the style of %f otherwise.

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

%c    8-bit unsigned character (unsigned char).

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

%C    16-bit UTF-16 code unit (unichar).

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

%s    Null-terminated array of 8-bit unsigned characters.

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

%S    Null-terminated array of 16-bit UTF-16 code units.

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

%p    Void pointer (void *), printed in hexadecimal with the digits 0–9 and lowercase a–f, with a leading 0x.

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

%n    The argument shall be a pointer to an integer into which is written the number of bytes written to the output so far by this call to one of the fprintf() functions.

The n format specifier seems unsupported in Swift 4+

%a    64-bit floating-point number (double), printed in scientific notation with a leading 0x and one hexadecimal digit before the decimal point using a lowercase p to introduce the exponent.

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

%A    64-bit floating-point number (double), printed in scientific notation with a leading 0X and one hexadecimal digit before the decimal point using a uppercase P to introduce the exponent.

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

Flags

'    The integer portion of the result of a decimal conversion ( %i, %d, %u, %f, %F, %g, or %G ) shall be formatted with thousands' grouping characters. For other conversions the behavior is undefined. The non-monetary grouping character is used.

The ' flag seems unsupported in Swift 4+

-    The result of the conversion shall be left-justified within the field. The conversion is right-justified if this flag is not specified.

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

+    The result of a signed conversion shall always begin with a sign ( '+' or '-' ). The conversion shall begin with a sign only when a negative value is converted if this flag is not specified.

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

<space>    If the first character of a signed conversion is not a sign or if a signed conversion results in no characters, a <space> shall be prefixed to the result. This means that if the <space> and '+' flags both appear, the <space> flag shall be ignored.

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

#    Specifies that the value is to be converted to an alternative form. For o conversion, it increases the precision (if necessary) to force the first digit of the result to be zero. For x or X conversion specifiers, a non-zero result shall have 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g , and G conversion specifiers, the result shall always contain a radix character, even if no digits follow the radix character. Without this flag, a radix character appears in the result of these conversions only if a digit follows it. For g and G conversion specifiers, trailing zeros shall not be removed from the result as they normally are. For other conversion specifiers, the behavior is undefined.

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

0    For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversion specifiers, leading zeros (following any indication of sign or base) are used to pad to the field width; no space padding is performed. If the '0' and '-' flags both appear, the '0' flag is ignored. For d, i, o, u, x, and X conversion specifiers, if a precision is specified, the '0' flag is ignored. If the '0' and '" flags both appear, the grouping characters are inserted before zero padding. For other conversions, the behavior is undefined.

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

Width modifiers

If the converted value has fewer bytes than the field width, it shall be padded with spaces by default on the left; it shall be padded on the right if the left-adjustment flag ( '-' ) is given to the field width. The field width takes the form of an asterisk ( '*' ) or a decimal integer.

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

Precision modifiers

An optional precision that gives the minimum number of digits to appear for the d, i, o, u, x, and X conversion specifiers; the number of digits to appear after the radix character for the a, A, e, E, f, and F conversion specifiers; the maximum number of significant digits for the g and G conversion specifiers; or the maximum number of bytes to be printed from a string in the s and S conversion specifiers. The precision takes the form of a period ( '.' ) followed either by an asterisk ( '*' ) or an optional decimal digit string, where a null digit string is treated as zero. If a precision appears with any other conversion specifier, the behavior is undefined.

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

Length modifiers

h    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a short or unsigned short argument.

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

hh    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a signed char or unsigned char argument.

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

l    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a long or unsigned long argument.

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

ll, q    Length modifiers specifying that a following d, o, u, x, or X conversion specifier applies to a long long or unsigned long long argument.

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

L    Length modifier specifying that a following a, A, e, E, f, F, g, or G conversion specifier applies to a long double argument.

I wasn't able to pass a CLongDouble argument to format in Swift 4+

z    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a size_t.

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

t    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a ptrdiff_t.

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

j    Length modifier specifying that a following d, o, u, x, or X conversion specifier applies to a intmax_t or uintmax_t argument.

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

这篇关于支持哪些 Swift 字符串格式说明符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆