格式化 Swift 中的字符串
Formatting strings in Swift
在某些语言中,例如 C#,您可以通过以下方式创建字符串:
"String {0} formatted {1} "
然后通过传入要格式化的值,使用 String.format
对其进行格式化。
上面的声明很好,因为你在创建字符串的时候不需要知道它的参数是什么类型。
我试图在 Swift 中找到类似的方法,但我发现的是类似于以下格式的内容:
"String %d formatted %d"
这需要您使用 String(format: , parameters)
格式化字符串。这不好,因为在声明字符串时您还必须知道参数类型。
在 Swift 中是否有类似的方法,我不必知道参数类型?
在 Swift 中,类型需要符合 CustomStringConvertible protocol 才能在字符串中使用。这也是字符串插值中使用的类型的要求,如下所示:
"Integer value \(intVal) and double value \(doubleVal)"
了解 CustomStringConvertible 后,您可以创建自己的函数来满足您的需求。以下函数根据给定的参数格式化字符串并打印它。它使用 {}
作为参数的占位符,但您可以将其更改为您想要的任何内容。
func printWithArgs(string: String, argumentPlaceHolder: String = "{}", args: CustomStringConvertible...) {
var formattedString = string
// Get the index of the first argument placeholder
var nextPlaceholderIndex = string.range(of: argumentPlaceHolder)
// Index of the next argument to use
var nextArgIndex = 0
// Keep replacing the next placeholder as long as there's more placeholders and more unused arguments
while nextPlaceholderIndex != nil && nextArgIndex < args.count {
// Replace the argument placeholder with the argument
formattedString = formattedString.replacingOccurrences(of: argumentPlaceHolder, with: args[nextArgIndex].description, options: .caseInsensitive, range: nextPlaceholderIndex)
// Get the next argument placeholder index
nextPlaceholderIndex = formattedString.range(of: argumentPlaceHolder)
nextArgIndex += 1
}
print(formattedString)
}
printWithArgs(string: "First arg: {}, second arg: {}, third arg: {}", args: "foo", 4.12, 100)
// Prints: First arg: foo, second arg: 4.12, third arg: 100
使用自定义实现可以让您更好地控制它并调整它的行为。例如,如果您愿意,可以修改此代码以显示相同的参数多次使用 {1}
和 {2}
等占位符,您可以按相反的顺序填写参数等
有关 Swift 中字符串插值的更多信息:https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-ID292
使用这个:
let printfOutput = String(format:"%@ %2.2d", "string", 2)
它与 printf 或 Obj-C 格式相同。
你也可以这样搭配:
let parm = "string"
let printfOutput = String(format:"\(parm) %2.2d", 2)
编辑:感谢 MartinR(他无所不知 ;-)
Be careful when mixing string interpolation and formatting. String(format:"\(parm) %2.2d", 2)
will crash if parm contains a percent character. In (Objective-)C, the clang compiler will warn you if a format string is not a string literal.
这为黑客攻击提供了一些空间:
let format = "%@"
let data = "String"
let s = String(format: "\(format)", data) // prints "String"
与在编译时解析格式字符串的 Obj-C 相比,Swift 不这样做,只是在运行时解释它。
在某些语言中,例如 C#,您可以通过以下方式创建字符串:
"String {0} formatted {1} "
然后通过传入要格式化的值,使用 String.format
对其进行格式化。
上面的声明很好,因为你在创建字符串的时候不需要知道它的参数是什么类型。
我试图在 Swift 中找到类似的方法,但我发现的是类似于以下格式的内容:
"String %d formatted %d"
这需要您使用 String(format: , parameters)
格式化字符串。这不好,因为在声明字符串时您还必须知道参数类型。
在 Swift 中是否有类似的方法,我不必知道参数类型?
在 Swift 中,类型需要符合 CustomStringConvertible protocol 才能在字符串中使用。这也是字符串插值中使用的类型的要求,如下所示:
"Integer value \(intVal) and double value \(doubleVal)"
了解 CustomStringConvertible 后,您可以创建自己的函数来满足您的需求。以下函数根据给定的参数格式化字符串并打印它。它使用 {}
作为参数的占位符,但您可以将其更改为您想要的任何内容。
func printWithArgs(string: String, argumentPlaceHolder: String = "{}", args: CustomStringConvertible...) {
var formattedString = string
// Get the index of the first argument placeholder
var nextPlaceholderIndex = string.range(of: argumentPlaceHolder)
// Index of the next argument to use
var nextArgIndex = 0
// Keep replacing the next placeholder as long as there's more placeholders and more unused arguments
while nextPlaceholderIndex != nil && nextArgIndex < args.count {
// Replace the argument placeholder with the argument
formattedString = formattedString.replacingOccurrences(of: argumentPlaceHolder, with: args[nextArgIndex].description, options: .caseInsensitive, range: nextPlaceholderIndex)
// Get the next argument placeholder index
nextPlaceholderIndex = formattedString.range(of: argumentPlaceHolder)
nextArgIndex += 1
}
print(formattedString)
}
printWithArgs(string: "First arg: {}, second arg: {}, third arg: {}", args: "foo", 4.12, 100)
// Prints: First arg: foo, second arg: 4.12, third arg: 100
使用自定义实现可以让您更好地控制它并调整它的行为。例如,如果您愿意,可以修改此代码以显示相同的参数多次使用 {1}
和 {2}
等占位符,您可以按相反的顺序填写参数等
有关 Swift 中字符串插值的更多信息:https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-ID292
使用这个:
let printfOutput = String(format:"%@ %2.2d", "string", 2)
它与 printf 或 Obj-C 格式相同。
你也可以这样搭配:
let parm = "string"
let printfOutput = String(format:"\(parm) %2.2d", 2)
编辑:感谢 MartinR(他无所不知 ;-)
Be careful when mixing string interpolation and formatting.
String(format:"\(parm) %2.2d", 2)
will crash if parm contains a percent character. In (Objective-)C, the clang compiler will warn you if a format string is not a string literal.
这为黑客攻击提供了一些空间:
let format = "%@"
let data = "String"
let s = String(format: "\(format)", data) // prints "String"
与在编译时解析格式字符串的 Obj-C 相比,Swift 不这样做,只是在运行时解释它。