#3 字符串和字符(Strings and Characters

2018-08-21  本文已影响49人  JamesSawyer

swift相对于JS,

1.多行字符

表示方式是:

let quotation = """
这是第一行
这是第二行
""";

个人感觉这个就是JS中简陋版的字符串模板,一些示例

#1 一行写不下, 可以用 '\' 进行换行
let quotation = """
这是第一行,\
这还是第一行的内容,太长了就换一行
这是第二行
""";

#2 最底下的 """ 的决定空格数 或者说缩进
let quotation = """
    这是第一行,
        这是第二行
    这是第3行
    """; // 注意这个前面有4个空格,因为放置位置在此.
// 等价于
let quotation = """
这是第一行,
    这是第二行
这是第3行
""";

#3 对 """ 进行转义
# 如果字符串中正好存在 """ 转义方式有2种: \""" 或者 \"\"\"
let threeDoubleQuotationMarks = """
Escaping the first quotation mark \"""
Escaping all three quotation marks \"\"\"
"""

#4 多个多行字符串结合
let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// 打印两行:
// one
// twothree

// 如果想要换行 则需要注意这样写
let goodStart = """
one
two

"""
let end = """
three
"""
print(goodStart + end)
// 打印三行:
// one
// two
// three

2.需要转义的字符

字符串字面量需转义的字符:

示例:

let wiseWord = "\"想象力比知识更重要\" - 爱因斯坦"
let dollarSign = "\u{24}" // $ Unicode标量为 U+0024
let sparklingHeart = "\u{1F496}" // 💖,Unicode 标量 U+1F496

3.字符串插值(string interpolation)

使用 \(variables || expression) 的形式进行插值操作, 这个等同于JS中的 ${}

let count = 5
print("I have \(count) apples") // I have 5 apples

4.字符串的可变性

这里只提一点,就是swift中用 let 声明的表示常量,这和JS中的 const 一样,但是JS中也有 let 关键词,注意别混淆了,因此在swift中下面做法是错误的:

let greet = "hello"
greet += " world" // error 常量字符串不可以被修改

5.Character 类型

注意有些语言中,这个类型称之为 Char,声明时用单引号,但是swift中Character类型用 双引号 进行声明

let aChar: Character = "A"
let charArray: [Character] = ["a", "b", "c"]

另外一般认为String类型是character类型的集合, swift中可以使用 for-in 对字符串进行遍历操作

let str = "Dog!🐶"
for character in "Dog!🐶" {
    print(character)
}
// D
// o
// g
// !
// 🐶

// 另外可以通过 type(of:) 方法来判断是否是Character类型
for char in "Dog!🐶" {
    print(type(of: char))
}
// 打印
// Character (重复5遍)

String 和 Character 类型之间的一些转换和方法

#1 将Character数组转换为字符串
# 使用 String 构造器即可
let cat: [Character] = ["C", "A", "T"]
let catStr = String(cat) // "CAT"

#2 将Character字符添加到String中
# 使用 append 方法
var greet = "hello"
let exclamationMark = "!"
greet.append(exclamationMark) // 现在greet变为了 "hello!"

6.Unicode

个人感觉这部分比较麻烦。

通俗讲一个字符的写法可能由Unicode组成的写法不一样,但是最后结果是一样的:

let eAcute: Character = "\u{E9}"                         // é
// 这个相当于对上面 é = e +  ́ 的分解
let combinedEAcute: Character = "\u{65}\u{301}"          // e 后面加上  ́
print(eAcute == combinedEAcute) // true

7.字符串的操作

swift中目前为止感觉语法最难看的部分来了,个人感觉这种设计太复杂了。

isEmpty 属性 判断字符串是否为空

let emptyString = ""
// 或者 let emptyString = String()
if emptyString.isEmpty {
  print("这是一个空字符")
}
// "这是一个空字符"

字符串索引

因为不同字符可能会占用不同数量的内存空间,所以要知道 Character 的确定位置,就必须从 String 开头遍历每一个 Unicode 标量 直到结尾,因此, swift的字符串不能用整数做索引!!!

获取字符位置的方法大概有以下几种:

另外需要注意的是:

#1 获取字符串的长度
let koala = "Koala 🐨"
print(koala.count) // 7 , 可以看出 这里 🐨 占一个字符

#2 开始索引
let greet = "hello world!"
print(greet[greet.startIndex]) // "h"

#3 endIndex 属性不能作为一个字符串的有效下标!!!
let greet = "hello world!"
print(greet[greet.endIndex]) // error  Can't form a Character from an empty String

#4 获取最后一个字符
# 使用 index(before i: String.Index) 方法
let greet = "hello world!"
print(greet[greet.index(before: greet.endIndex)]) // "!"

#5 使用 index(after i: String.Index) 方法 获取第一个字符之后的字符
let greet = "hello world!"
print(greet[greet.index(after: greet.startIndex)]) // "e"

#6 使用 index(_ i: String.Index, offsetBy n: int) -> String.Index
let greet = "hello world!"
print(greet[greet.index(greet.startIndex, offsetBy: 4)]) // "o"

#7 使用 indices 创建 Range
let greet = "hello world!"
for index in greet.indices {
    print("\(greet[index])", terminator: "|")
}
// h|e|l|l|o| |w|o|r|l|d|!|Index(_compoundOffset: 0, _cache: Swift.String.Index._Cache.utf16)

字符串增删改查

主要用到这几个方法:

示例:

var greet = "hello"

// 在尾部添加单个字符 '!'
greet.insert("!", at: greet.endIndex) // "hello!"

// 在 '!' 前添加 "world" 字符段
greet.insert(contentOf: "world", at: greet.index(greet.endIndex, offsetBy: -1)) // "hello world!"

// 在尾部移除单个字符 '!'
// 返回被移除的字符 "!"
// 同时greet 变为 "hello world"
greet.remove(at: greet.index(before: greet.endIndex))

// 移除 " world"
// 注意 removeSubrange 接受的参数类型是 Range<String> 类型
// 需要使用到前面学习的区间的表示法
let range = greet.index(greet.index(greet.endIndex, offsetBy: -6))..<greet.endIndex
greet.removeSubrange(range) // "hello"

SubString 类型

当从字符串中获取一个子字符串,得到的是一个 SubString 实例,而不是 String 类型,Swift中如果需要短时间内操作字符串,才会使用SubString,如果要长时间保存结果,就把 SubString 转化为 String 的实例:

下面示例使用方法:

var greet = "hello, world!"
let index = greet.index(of: ",") ?? greet.endIndex
let beginning = greet[..<index] // beginning 的值为 "hello"
print(type(of: beginning)) // 打印其类型为 "SubString"

// 将其转化为 String 类型, 以便长期存储
let newString = String(beginning)

本章中其它的字符串方法

let greet = "hello, world";
print(greet.hasPrefix("hell")) // true
print(greet.hasSuffix("world")) // true

另外swift中好像没有类似JS中的 substring 方法对字符进行截取,原生的小伙伴告诉我可以自定义:

extension String {
  func substring(start: Int, end: Int = 0) -> String? {
    if start > end && end != 0 {
      return nil
    }
    
    let startIndex = self.index(self.startIndex, offsetBy: start)
    let endIndex = end == 0 ? self.endIndex : self.index(self.startIndex, offsetBy: end)
    
    return String(self[startIndex..<endIndex])
  }
}

// 使用
let greet = "hello, world!"
greet.sub(start: 3, end: 7) // "lo,"
greet.sub(start: 3) // "lo, world!"

总结

这一章主要讲了swift中的2种(加上SubString应该是3种)类型,以及字符串索引的操作,最复杂的Unicode的相关表示法此处忽略了,待后面再学习。另外介绍了一些操作字符串的方法,还有大把的方法暂时还未接触,待学习。

上一篇 下一篇

猜你喜欢

热点阅读