字符和字符串
本节,我们专门来讲讲数据类型中的String
类型及其操作。
什么是字符和字符串?
简单理解,字符就是英文字母,字符串就是多个英文字母,就是单词,词组,或句子。
当然,广义来说,所有你能用键盘敲出来的字符,然后用双引号""
包起来,都是字符或字符串。这里面当然也包括中文。
单独的字符场景较少,后面我们为了方便,统称为字符串。
操作字符串的意义?
语言是人类信息沟通的重要工具。
对字符的操作和加工处理是任何一门计算机语言的重头戏。确实,在英文世界中,对字符串处理的场景更多,但是我们仍然会遇到大量的场景,比如邮箱,号码,各类原始数据等,都需要进行大量的逻辑操作。
我们在之前说到数据类型的时候,对各种类型做了一个总结表格,还记得吗?
不记得也没有关系,现在再看一眼:
类型 | 说明 | 举例 | 备注 | |
---|---|---|---|---|
整型 | Int | 整数 | 1 | (32位范围) -2147483648 到 2147483647 |
(64位范围)-9223372036854775808 到 9223372036854775807 | ||||
浮点型 | Float | 小数(32位) | 3.14 | 范围:1.2E-38 到 3.4E+38 (~6 digits) |
Double | 小数(64位) | 范围:2.3E-308 到 1.7E+308 (~15 digits) | ||
布尔值 | Bool | 真/假 | True/False | 只有True,False这两个值 |
字符串 | String | 字符 | "hello" | |
可选类型 | Optional | 有/没有 |
我们重新梳理一下这个表格:
首先,除去布尔值,可选类型这种特殊的类型;接着,我们把整型和浮点型这两个同一称为数字型,现在,再看看这个表格:
类型 | 说明 | 举例 | 备注 | |
---|---|---|---|---|
数字型 | Int Double | 整数 | 1,1.2 | |
字符串 | String | 字符 | "hello" |
发现没有?计算机处理的所有的数据类型,就只剩下数字和字母(文字)了。而我们上一节讲过的运算符,很大程度上是针对数字的操作。
现在,就只剩下字母(文字)这个对象了!
定义字符串
最简单的方式,我们用双引号包裹一段字符,赋值给一个常量或变量,就定义好了一个字符串。
let someString = "Hello world"
var newString = "I love Swift"
不仅仅是英文字符,数字,汉字,被包裹后,也是字符串。
let numberString = "100"
let hanString = "你好"
print(type(of: hanString)) // String
如果是多行文字,需要换行,可以使用三引号包裹""" """
let multiLine =
"""
这里可以写多行文字。
当我们打印个常量时,多行的样式是保留的。
English is also available.
"""
print(multiLine)
字符串中的特殊含义
国王获得了点石成金的魔力,任何东西被他碰到都会变成金子,包括他要吃的食物,和他的女儿。
《盗梦空间》给了我们一个方法:找一个自己的“陀螺”!
刚才我们说,用双引号包裹起来的都是字符。那么,问题就来了。
假如我真的就是想打印一个双引号"
而已,怎么办?
print(""")
这样吗?你可以在Playground中试一下,显然是不行的。
再假如我想打印一个变量,当变量的值改变时,我的打印结果也自动变化。
var someString = "Hello"
print("someString") // 这样可以吗?
print(someString) // 或者这样呢?
显然,都是不行的,因为双号将包裹其中的一切符号都当成了字符。这里的“陀螺”就是反斜杠\
。
我们再试试第一个例子:print("\"")
,这样就正常了,因为Swift遇到双引号中的\
时,就会特殊对待,\
称为转义字符,它后面的字符都按照非字符处理。
打印变量的话,可以这样:
var someString = "Hello"
print("\(someString)") // 这样就可以正常显示,变量值改变,打印结果也会变
让我们继续看看还有哪些能转义:
转义字符 \0(空字符)、\\(反斜线)、\t(水平制表符)、\n(换行符)、\r(回车符)、\"(双引号)、\'(单引号)、\u{Unicode代码}。
问题又来了,我就是想打印反斜杠\
出来,而且我的文字里有好多,还有\n \()
什么的一大堆,都想按照原貌出现。好吧,一般情况下,我们给\
前面加个\
就可以了,如果觉得麻烦,可以直接用#
来包裹"
。
print(#"Line 1 \nLine 2"#)
上面这段代码就会直接打印出Line 1 \nLine 2
,中间不会换行。
访问字符串
定义了字符串之后,我们可以对字符串进行查询等访问操作。
对字符串的访问可以分为遍历,插值,统计,索引,子字符串,比较,检查前后缀等。
-
遍历
使用for循环,可以遍历字符串中的每一个字符。
for i in "Hello" {
print(i)
}
-
插值
我们之前使用过,就是使用\()
将变量或常量名放在一串双引号中。
let name = "Tom"
let greeting = "Hello \(name)!"
print(greeting) // Hello Tom!
-
统计
就是统计一串字符的数量。
let newString = "Hello world"
print(newString.count) // 11
// 空格也是计数的
-
索引
我们可以定义一串字符里面的某个字符的位置,他们可以是第一个位置string.startIndex
,最后一个位置的后一个位置string.endIndex
,某个位置之前一个位置string.index(before: string.endIndex)
,某个位置之后的位置string.index(after: string.startIndex)
,偏离某个位置n位string.index(string.startIndex, offsetBy: n)
。
var a = "Hello"
print(a[a.startIndex])
// H
print(a[a.index(before: a.endIndex)])
// o
print(a[a.index(after: a.startIndex)])
// e
print(a[a.index(a.startIndex, offsetBy: 3)])
// l
print(a[a.index(a.endIndex, offsetBy: -4)])
// e
-
子字符串
我们借用前面说过的定位,可以截取字符串的某一段。这么做的意义在于,子字符串是原字符串在内存空间的一部分,两者实际上是同一块内存空间,这样效率更高。
let a = "Hello"
// 定义了一个字符串
let tempIndex = a.index(a.startIndex, offsetBy: 2)
// 定义一个定位
let subA = a[a.startIndex..<tempIndex] //还记得区间运算符吗?
// 通过类似数组取值的方式,得到一个新字符串,它是a字符串的一部分
print(subA)
-
比较
字符串怎么比较呢?其实就是比两个字符串是不是相等。这里需要用到我们之前讲过的比较运算符,等于==
,不等于!=
。
let stringA = "Hello there!"
let stringB = "Hello world!"
if stringA == stringB {
print("两个字符串一样!")
} else if stringA != stringB {
print("两个字符串不一样!")
}
除了直接比较字符串的完整部分,还可以比较字符串的其中一部分。使用前缀hasPrefix(_:)
和后缀hasSuffix(_:)
。
// 定义三个字符串
let stringA = "Hello there!"
let stringB = "Hello world!"
let stringC = "This is another string."
// 定义一个变量,初始值为零,计数用。
var helloCount = 0
// 将三个字符串组合成一组。
let stringList = [stringA,stringB,stringC]
// 遍历,并判断是不是开头含“Hello”。如果有,就给计数变量加1.
for i in stringList{
if i.hasPrefix("Hello") {
helloCount += 1
}
}
// 输出结果
print("带有‘Hello’的字符串有\(helloCount)个。")
加工和编辑字符串
定义,访问字符串变量是不够的。我们还想对字符串进行加工和编辑。大体上,我们可以对字符串进行拼接,插入,和删除这几个编辑操作。
-
拼接
将两个字符串直接拼起来。可以使用+
,+=
,string.append()
。
var stringA = "Hello"
var stringB = " world"
var stringC = "!"
let newString = stringA + stringB
print(newString)
// Hello world
stringA += stringB
print(stringA)
// Hello world
stringA.append(stringC)
print(stringA)
// Hello world!
-
插入
结合我们之前对字符串做的定位,可以在固定位置插入某个新字符串,insert(contentsOf:at:)
,如果是插入单个字符,可以省略contensOf。
// 定义一个字符串
var a = "Hello"
// 定义一个定位
let tempIndex = a.endIndex
// 对字符串a进行insert操作
a.insert(contentsOf:" world", at: tempIndex)
// 打印并验证结果
print(a)
-
删除
同样的道理,我们也可以删除某段字符串。使用remove(at:)
删除某个位置的那一个字符,用removeSubrange(_:)
删除某个区间的字符。
var a = "Hello!"
a.remove(at: a.index(before: a.endIndex))
print(a)
// Hello
a.removeSubrange(a.index(a.startIndex, offsetBy: 2)..<a.endIndex)
print(a)
// He
小结与预告
到这里,我们已经讲解了关键的数据类型:数字和文字,并使用多种符号对它们进行各种操作。
还有一种情况,就是将多个数字或文字进行组合,并操作这个组合。
下节见!
网友评论