支持的Swift字符串格式说明符有哪些?

yc0p9oo0  于 2022-10-31  发布在  Swift
关注(0)|答案(3)|浏览(580)

在Swift中,我可以用格式说明符格式化String:

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

但是官方文档没有提供任何有关支持的格式说明符或如何构建类似于"%.03f"的模板的信息或链接:https://developer.apple.com/documentation/swift/string/3126742-init
它只说:
返回一个String对象,该对象通过将给定的格式字符串用作模板来初始化,剩余的参数值将被替换到该模板中。

xoefb8l8

xoefb8l81#

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

但是这个文档页面本身是不完整的,例如 flagsprecision 说明符和 width 说明符都没有提到。实际上,它声称遵循IEEE printf specifications (Issue 6, 2004 Edition),本身符合ISO C标准。所以这些说明符应该与我们在C printf中所拥有的相同,只是增加了一个用于Objective-C对象的%@说明符。和q长度修饰符,这两个说明符的文档质量较差。

说明符

每个转换规范都是由“%”字符或字符序列“%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位整数(无符号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 % s 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!)

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

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

%s中的文件夹 以空值终止的8位无符号字符数组。

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

%S个 以空值结尾的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()函数之一写入输出的字节数。

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

%个 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)

如果有符号转换的第一个字符不是符号,或者如果有符号转换没有产生任何字符,则应在结果前加上前缀。这意味着,如果和“+”标志同时出现,则应忽略该标志。

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)

长度修饰符

小时 长度修饰词,指定后面的d、o、u、x或X转换规范套用至short或unsigned short参数。

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


小时 长度修饰词,指定后面的d、o、u、x或X转换规范套用至带负数号的char或不带负数号的char参数。

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

升 长度修饰词,指定后面的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)

左 长度修饰词,指定后面的a、A、e、E、f、F、g或G转换规范套用至Long Double参数。

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

Z轴 指定后面的d、o、u、x或X转换规范套用至size_t的长度修饰词。

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

测试 长度修饰词,指定后面的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)
2ul0zpep

2ul0zpep2#

可能支持以下所有项,其中总结了NSStringsource)支持的格式说明符。
NSString化方法和CFString格式化函数支持的格式说明符遵循IEEE printf specification;下表(表1)总结了这些说明符。请注意,您也可以使用“n$“位置说明符,如%1$@ %2$s。有关详细信息,请参阅IEEE printf specification。您还可以将这些格式说明符与NSLog函数一起使用。

格式说明符(表1)

| 说明符|项目名称|
| - -|- -|
| %@| Objective-C对象,如果descriptionWithLocale:可用,则打印为description返回的字符串,否则打印为description返回的字符串。也可用于CFTypeRef对象,返回CFCopyDescription函数的结果。|
| %%个|'%'个字符。|
| %d%D|有符号32位整数(int)。|
| %u%U|无符号32位整数(unsigned int)。|
| %x|无符号32位整数(unsigned int),使用数字0--9和小写字母a--f以十六进制形式输出。|
| x1米20英寸|无符号32位整数(unsigned int),使用数字0--9和大写字母A--F以十六进制形式显示。|
| %o%O|无符号32位整数(unsigned int),以八进制打印。|
| x1米25英寸1x| 64位浮点数(double)。|
| %e个|64比特浮点数(double),以科学记数法打印,使用小写e来引入指数。|
| %E个|64位浮点数(double),以科学记数法打印,使用大写E引入指数。|
| %g| 64位浮点数(double),如果指数小于--4或大于或等于精度,则以%e的样式输出,否则以%f的样式输出。|
| x1米35英寸|64位浮点数(double),如果指数小于--4或大于或等于精度,则以%E的样式输出,否则以%f的样式输出。|
| x1米39英寸1x| 8位无符号字符(unsigned char)。|
| %C个|16位UTF-16代码单元(unichar)。|
| %s个|以空值终止的8位无符号字符数组。由于%s说明符导致以系统默认编码解释字符,因此结果可能是可变的,尤其是对于从右向左的语言。例如,对于RTL,%s在字符不是强方向性时插入方向标记。因此,最好避免使用%s并显式指定编码。|
| %S|以空值结尾的16位UTF-16代码单元数组。|
| %p个|空指针(void *),以十六进制形式打印,包含数字0--9和小写a--f,并带有前导0x。|
| %a| 64位浮点数(double),以科学记数法打印,在小数点前有一个前导0x和一个十六进制数字,并使用小写p引入指数。|
| x1米55英寸1x| 64位浮点数(double),以科学记数法打印,在小数点前有一个前导0X和一个十六进制数字,并使用大写P引入指数。|
| %F个|64位浮点数(double),以十进制表示法打印。|

长度修饰符(表2)

| 长度修改子|项目名称|
| - -|- -|
| h|长度修饰词,指定后面的douxX转换规范套用至shortunsigned short参数。|
| hh个|长度修饰词,指定后面的douxX转换规范套用至signed charunsigned char参数。|
| l个|长度修饰词,指定后面的douxX转换规范套用至longunsigned long参数。|
| llq|长度修饰词,指定后面的douxX转换规范套用至long longunsigned long long参数。|
| L个|长度修饰词,指定后面的aAeEfFgG转换规范套用至long double参数。|
| z个|长度修饰词,指定后面的douxX转换规范套用至size_t。|
| t个月|长度修饰词,指定后面的douxX转换规范套用至ptrdiff_t。|
| j个|长度修饰词,指定后面的douxX转换规范套用至intmax_tuintmax_t参数。|
长度修饰符示例:


# include <limits.h>

// ...

NSString *text = [NSString stringWithFormat:@"Signed %hhd, Unsigned %hhu", CHAR_MIN, UCHAR_MAX];

或在斯威夫特:

let text = String(format: "Signed %hhd, Unsigned %hhu", CChar.min, CUnsignedChar.max)

平台依赖项

OS X使用几种数据类型--NSIntegerNSUIntegerCGFloatCFIndex--来提供在32位和64位环境中表示值的一致方法。在32位环境中,NSIntegerNSUInteger被定义为intunsigned int,在64位环境中,NSIntegerNSUInteger分别被定义为longunsigned long。为了避免根据平台使用不同的printf样式类型说明符,可以使用表3中所示的说明符。注意,在某些情况下,可能必须强制转换该值。

表3数据类型的格式说明符

| 型号|格式说明符|注意事项|
| - -|- -|- -|
| x1米138英寸1x| %ld%lx|将值转换为long。|
| NSUInteger个|%lu%lx|将值转换为unsigned long。|
| CGFloat个|%f%g| %f在格式化时适用于浮点数和双精度数;但是注意下面描述的用于扫描的技术。|
| 一个月150个月|%ld%lx|与NSInteger相同。|
| 指示器|%p%zx| %p0x添加到输出的开头。如果不希望这样,请使用%zx,并且不进行类型转换。|
下列范例说明如何使用%ld来格式化NSInteger,以及如何使用转型。

NSInteger i = 42;
printf("%ld\n", (long)i);

除了表3中提到的注意事项外,还有一种额外的扫描情况:您必须区分floatdouble的类型。您应该将%f用于浮点型,将%lf用于双精度型。如果您需要将scanf(或其变体)与CGFloat一起使用,请改为切换到double,并将double复制到CGFloat

CGFloat imageWidth;
double tmp;
sscanf (str, "%lf", &tmp);
imageWidth = tmp;

请记住,%lf在32位或64位平台上都不能正确表示CGFloat,这与%ld不同,%ld在所有情况下都适用于long

sauutmhj

sauutmhj3#

"雨燕5"

let timeFormatter = DateFormatter()
    let dateFormat = DateFormatter.dateFormat(fromTemplate: "jm", 
                                    options: 0, locale: Locale.current)!
    timeFormatter.dateFormat  = dateFormat

相关问题