字符串和字符

2017-09-20  本文已影响7人  寥寥十一

字符串字面量

字符串字面量是由双引号 ( "" ) 包裹着的具 有固定顺序的文本字符 。 字符串字面量可以用于为常量和变量提供初始值:

let someString = "Some string literal value"

注意 someString 常量通过字符串字面量进行初始化,Swift 会推断该常量为 String 类型。

初始化空字符串

var emptyString = "" // 空字符串字面量 
var anotherEmptyString = String() // 初始化方法
// 两个字符串均为空并等价。

您可以通过检查其 Bool 类型的 isEmpty 属性来判断该字符串是否为空:

if emptyString.isEmpty {
    print("Nothing to see here")
}
// 打印输出:"Nothing to see here"

字符串可变性

您可以通过将一个特定字符串分配给一个变量来对其进行修改,或者分配给一个常量来保证其不会被修改:

var variableString = "Horse"
variableString += " and carriage"
// variableString 现在为 "Horse and carriage"
let constantString = "Highlander"
constantString += " and another Highlander"
// 这会报告一个编译错误 (compile-time error) - 常量字符串不可以被修改。

字符串是值类型

Swift 的 String 类型是值类型。 如果您创建了一个新的字符串,那么当其进行常量、变量赋值操作,或在函数/ 方法中传递时,会进行值拷贝。 任何情况下,都会对已有字符串值创建新副本,并对该新副本进行传递或赋值操 作。

使用字符

您可通过 for-in 循环来遍历字符串中的 characters 属性来获取每一个字符的值:

for character in "Dog!?".characters {
    print(character)
}
// D
// o
// g
// !
// ?

连接字符串和字符

字符串可以通过加法运算符( + )相加在一起(或称“连接”)创建一个新的字符串:

let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2 
// welcome 现在等于 "hello there"

您也可以通过加法赋值运算符 ( += ) 将一个字符串添加到一个已经存在字符串变量上:

var instruction = "look over"
instruction += string2
// instruction 现在等于 "look over there"

您可以用 append() 方法将一个字符附加到一个字符串变量的尾部:

let exclamationMark: Character = "!" welcome.append(exclamationMark)
// welcome 现在等于 "hello there!"

字符串插值

字符串插值是一种构建新字符串的方式,可以在其中包含常量、变量、字面量和表达式。 您插入的字符串字面量 的每一项都在以反斜线为前缀的圆括号中:

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)" 
// message 是 "3 times 2.5 is 7.5"

计算字符数量

如果想要获得一个字符串中 Character 值的数量,可以使用字符串的 characters 属性的 count 属性:

let unusualMenagerie = "Koala ?, Snail ?, Penguin ?, Dromedary ?" 
print("unusualMenagerie has \(unusualMenagerie.characters.count) characters") 
// 打印输出 "unusualMenagerie has 40 characters"

注意在 Swift 中,使用可拓展的字符群 作为 值来连接或改变字符串时,并不一定会更改字符串的字 符数量。

访问和修改字符串

字符串索引 每一个String 值都有一个关联的索引(index)类型,String.Index ,它对应着字符串中的每一个 Character的位 置。
前面提到,不同的字符可能会占用不同数量的内存空间,所以要知道 Character 的确定位置,就必须从 String开 头遍历每一个 Unicode 标量直到结尾。因此,Swift 的字符串不能用整数(integer)做索引。
你可以使用下标语法来访问 String 特定索引的 Character 。

 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

试图获取越界索引对应的 Character ,将引发一个运行时错误。

 greeting[greeting.endIndex] // error
 greeting.index(after: endIndex) // error

使用 characters 属性的 indices 属性会创建一个包含全部索引的范围(Range),用来在一个字符串中访问单 个字符。

 for index in greeting.characters.indices {
    print("\(greeting[index]) ", terminator: "")
}
// 打印输出 "G u t e n T a g ! "

插入和删除
调用 insert(_:at:) 方法可以在一个字符串的指定索引插入一个字符,调用 insert(contentsOf:at:) 方法可 以在一个字符串的指定索引插入一个段字符串。

var welcome = "hello"
welcome.insert("!", at: welcome.endIndex) 
// welcome 变量现在等于 "hello!"
welcome.insert(contentsOf:" there".characters, at: welcome.index(before: welcome.endIndex)) 
// welcome 变量现在等于 "hello there!"

调用 remove(at:) 方法可以在一个字符串的指定索引删除一个字符,调用 removeSubrange(_:) 方法可以在一 个字符串的指定索引删除一个子字符串。

welcome.remove(at: welcome.index(before: welcome.endIndex)) 
// welcome 现在等于 "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex 
welcome.removeSubrange(range)
// welcome 现在等于 "hello"

比较字符串

字符串/字符相等
字符串/字符可以用等于操作符( == )和不等于操作符( != )

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")
}
// 打印输出 "These two strings are considered equal"

前缀/后缀相等
通过调用字符串的 hasPrefix(_:) / hasSuffix(_:) 方法来检查字符串是否拥有特定前缀/后缀,两个方法均接收一 个 String 类型的参数,并返回一个布尔值。
下面的例子以一个字符串数组表示莎士比亚话剧《罗密欧与朱丽叶》中前两场的场景位置:

 let romeoAndJuliet = [
     "Act 1 Scene 1: Verona, A public place",
     "Act 1 Scene 2: Capulet's mansion",
     "Act 1 Scene 3: A room in Capulet's mansion",
     "Act 1 Scene 4: A street outside Capulet's mansion",
     "Act 1 Scene 5: The Great Hall in Capulet's mansion",
     "Act 2 Scene 1: Outside Capulet's mansion",
     "Act 2 Scene 2: Capulet's orchard",
     "Act 2 Scene 3: Outside Friar Lawrence's cell",
     "Act 2 Scene 4: A street in Verona",
     "Act 2 Scene 5: Capulet's mansion",
     "Act 2 Scene 6: Friar Lawrence's cell"
]

您可以调用 hasPrefix(_:) 方法来计算话剧中第一幕的场景数:

 var act1SceneCount = 0
 for scene in romeoAndJuliet {
     if scene.hasPrefix("Act 1 ") {
         act1SceneCount += 1
} }
print("There are \(act1SceneCount) scenes in Act 1") 
// 打印输出 "There are 5 scenes in Act 1"

相似地,您可以用 hasSuffix(_:) 方法来计算发生在不同地方的场景数:

var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
    if scene.hasSuffix("Capulet's mansion") {
        mansionCount += 1
    } else if scene.hasSuffix("Friar Lawrence's cell") {
        cellCount += 1
} }
print("\(mansionCount) mansion scenes; \(cellCount) cell scenes") 
// 打印输出 "6 mansion scenes; 2 cell scenes"
上一篇下一篇

猜你喜欢

热点阅读