字符字面量(String Literals)
多行字面量
使用 """ 包围字符串
let quotation = """
The White Rabbit put on his spectacles. "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
特殊字符
\0 null
\\ 反斜杠
\t 水平制表符
\n 换行符
\r 回车符
'\n' is the default in Unix, '\r\n' is the default in Windows.
\" 双引号
\' 单引号
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\u{2665}" // ♥, Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // 💖, Unicode scalar U+1F496
string 是值类型( copy-by-default)
所谓值类型是值,当赋值给另一个变量是,它的值被拷贝给另一个变量.
Swift的编译器优化了字符串的使用,只有在必须的时候实际的复制才会发生.
Character
访问 string里的 character
for character in "Dog!🐶" {
print(character)
}
// D
// o
// g
// !
// 🐶
连接String和Character
let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome now equals "hello there"
var instruction = "look over"
instruction += string2
// instruction now equals "look over there"
let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"
多行字符连接
let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// Prints two lines:
// one
// twothree
let goodStart = """
one
two
"""
print(goodStart + end)
// Prints three lines:
// one
// two
// three
字符串插值
构建新字符串的方式,可在其中包含常量、变量、字面量和表达式
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message 是 "3 times 2.5 is 7.5"
Unicode
是一个国际标准,用于文本的编码和表示。
Unicode 标量
Swift 的String类型是基于 Unicode 标量 建立的。 Unicode 标量是对应字符或者修饰符的唯一的21位数字,例如U+0061表示小写的拉丁字母(LATIN SMALL LETTER A)("a"),U+1F425表示小鸡表情(FRONT-FACING BABY CHICK) ("🐥")。
注意: Unicode 码位(code poing) 的范围是U+0000到U+D7FF或者U+E000到U+10FFFF。Unicode 标量不包括 Unicode 代理项(surrogate pair) 码位,其码位范围是U+D800到U+DFFF
可扩展的字形群集
每一个 Swift 的Character类型代表一个可扩展的字形群。 一个可扩展的字形群是一个或多个可生成人类可读的字符 Unicode 标量的有序排列。
每一个 Swift 的Character类型代表一个可扩展的字形群。 一个可扩展的字形群是一个或多个可生成人类可读的字符 Unicode 标量的有序排列。
举个例子,字母é可以用单一的 Unicode 标量é(LATIN SMALL LETTER E WITH ACUTE, 或者U+00E9)来表示。然而一个标准的字母e(LATIN SMALL LETTER E或者U+0065) 加上一个急促重音(COMBINING ACTUE ACCENT)的标量(U+0301),这样一对标量就表示了同样的字母é。 这个急促重音的标量形象的将e转换成了é。
在这两种情况中,字母é代表了一个单一的 Swift 的Character值,同时代表了一个可扩展的字形群。 在第一种情况,这个字形群包含一个单一标量;而在第二种情况,它是包含两个标量的字形群:
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e 后面加上 ́
// eAcute 是 é, combinedEAcute 是 é
计算字符数量
let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"
注意在 Swift 中,使用可拓展的字符群集作为Character值来连接或改变字符串时,并不一定会更改字符串的字符数量。
例如,如果你用四个字符的单词cafe初始化一个新的字符串,然后添加一个COMBINING ACTUE ACCENT(U+0301)作为字符串的结尾。最终这个字符串的字符数量仍然是4,因为第四个字符是é,而不是e:
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in cafe is 4"
word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.count)")
// Prints "the number of characters in café is 4"
访问和修改字符串
可以通过方法,属性,下标语法
字符串索引
每一个String值都有一个关联的索引(index)类型,String.Index,它对应着字符串中的每一个Character的位置。
由于不同的字符可能占用不同数量的内存空间,所以要确定character的位置,就必须从string开头遍历每一个Unicode标量知道结尾,因此,Swift 的字符串不能用整数(integer)做索引。
使用startIndex属性可以获取一个String的第一个Character的索引。使用endIndex属性可以获取最后一个Character的后一个位置的索引。因此,endIndex属性不能作为一个字符串的有效下标。如果String是空串,startIndex和endIndex是相等的。
通过调用 String 的 index(before:) 或 index(after:) 方法,可以立即得到前面或后面的一个索引。您还可以通过调用 index(_:offsetBy:) 方法来获取对应偏移量的索引,这种方式可以避免多次调用 index(before:) 或 index(after:) 方法。
let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a
使用indices 属性会创建一个包含全部索引的范围(Range),用来在一个字符串中访问单个字符。
for index in greeting.indices {
print("\(greeting[index]) ", terminator: "")
}
// 打印输出 "G u t e n T a g ! "
插入和移除
插入单个字符 和 字符串
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"
移除单个字符 和 字符串
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
Substrings
当你从一个string得到一个substring --例如 使用subscript或者方法prefix(_:). Substrings与strings有大部分相同的方法.
但是你需要使用substring的时间一般很短.当你需要长期保持结果时,你可以把substring转成string
let greeting = "Hello, world!"
let index = greeting.index(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
// Convert the result to a String for long-term storage.
let newString = String(beginning)
出于性能的考虑,substring会重用原始字符串的部分存储。
字符比较
String 和 Character 的相等
比较相等使用 "=="
不相等 "!="
let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
print("These two strings are considered equal")
}
// Prints "These two strings are considered equal"
两个字符串被认为是相等的如果他们可扩展的字形群集(extended grapheme clusters)是相同的
前缀/后缀相等
通过调用字符串的hasPrefix(:)/hasSuffix(:)方法来检查字符串是否拥有特定前缀/后缀,两个方法均接收一个String类型的参数,并返回一个布尔值
字符串的 Unicode 表示形式
当一个 Unicode 字符串被写进文本文件或者其他储存时,字符串中的 Unicode 标量会用 Unicode 定义的几种编码格式(encoding forms)编码。每一个字符串中的小块编码都被称代码单元(code units)。这些包括 UTF-8 编码格式(编码字符串为8位的代码单元), UTF-16 编码格式(编码字符串位16位的代码单元),以及 UTF-32 编码格式(编码字符串32位的代码单元)。
Swift 提供了几种不同的方式来访问字符串的Unicode表示形式.您可以利用for-in来对字符串进行遍历,从而以Unicode可扩展的字符群集的方式访问每一个character值.
另外,能够以其他三种Unicode兼容的方式访问字符串的值
- UTF-8代码单元集合(利用字符串的utf8属性来进行访问)
- UTF-16代码单元集合(利用字符串的utf16属性来进行访问)
- 21位的Unicode标量值,也及时字符串的UTF-32编码格式(利用字符串的unicodeScalars属性进行访问)
下面由D,o,g,‼(DOUBLE EXCLAMATION MARK, Unicode 标量 U+203C)和🐶(DOG FACE,Unicode 标量为U+1F436)组成的字符串中的每一个字符代表着一种不同的表示:
let dogString = "Dog!!🐶"
UTF-8表示
你可以通过遍历String的utf8属性来访问它的UTF-8表示。 其为String.UTF8View类型的属性,UTF8View是无符号8位 (UInt8) 值的集合,每一个UInt8值都是一个字符的 UTF-8 表示:
for codeUnit in dogString.utf8 {
print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 226 128 188 240 159 144 182 "
UTF-16表示
你可以通过遍历String的utf16属性来访问它的UTF-16表示.
其为String.UTF16View类型的属性,UTF16View是无符号16位(UInt16)
值得集合,每一个UInt16值都是一个字符的UTF-16表示:
for codeUnit in dogString.utf16 {
print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 55357 56374 "
Unicode 标量表示
您可以通过遍历String值的unicodeScalars属性来访问它的 Unicode 标量表示。 其为UnicodeScalarView类型的属性,UnicodeScalarView是UnicodeScalar类型的值的集合。 UnicodeScalar是21位的 Unicode 代码点。
每一个UnicodeScalar拥有一个value属性,可以返回对应的21位数值,用UInt32来表示:
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "