获取前缀
好吧,经历了上一节的各种“说教”,也许现在你真的已经做好准备要用全新的姿态面对Swift中的字符串处理了。然而,当你想获取一个字符串中的前缀时,根据我们前面讲到的内容,你写下了下面的代码:
let beg = cafee.startIndex
let end = cafee.index(cafee.startIndex, offsetBy: 3)
cafee[beg ..< end] // Caf
看到这,估计你还是会觉得很受挫折,毕竟这难道不是cafee[0 ..< 3]就能解决的问题么?为了避免上面这样的代码,Swift提供了一个叫做prefix(_:)的方法,它返回一个特定的CharacterView:
String(cafee.characters.prefix(3)) // Caf
当我们用这个view创建String对象的时候,就可以看到结果和之前是一样的。但这样用起来,就方便多了。
遍历字符串中的每一个字符
有时候,我们需要遍历字符串中的每一个字符,通过characters属性,我们可以很容易办到:
var mixStr = "Swift很有趣"
for (index, value) in mixStr.characters.enumerated() {
print("\(index): \(value)")
}
// 0: S
// 1: w
// 2: i
// 3: f
// 4: t
// 5: 很
// 6: 有
// 7: 趣
上面的代码,会返回注释中的结果。其中enumerated方法会返回一个Tuple序列,其中的每一个元素表示对应字符在字符串中位置以及值。从结果就可以看到,Swift可以很好的识别字符串中的中英文字符,让unicode字符串处理起来和普通的字符数组一样。
插入内容
当我们要在字符串中插入内容时,要先获得目标位置的Index对象,然后使用insert方法。例如:
if let index = mixStr.characters.index(of: "很") {
mixStr.insert(contentsOf: " 3.0".characters, at: index)
// "Swift 3.0很有趣"
}
这样,我们就在原来“很”字的位置,插入了“ 3.0”。
基于Range的查找和替换
借助于由String.Index构成的Range对象,我们可以很方便的替换某个范围的字符串。例如,要把mixStr中的“很有趣”,替换成“is interesting”,可以这样:
if let cnIndex = mixStr.characters.index(of: "很") {
// 2. Replace a specific range
mixStr.replaceSubrange(
cnIndex ..< mixStr.endIndex,
with: " is interesting!")
// Swift 3.0 is interesting!
}
首先,我们使用cnIndex ..< mixStr.endIndex得到了要替换的字符串的Range对象。然后,直接调用replaceSubrange(_:with:),用with中的值替换Range中的值就可以了;
字符串切片
在上节中,我们提到过String.characters是有集合类型的行为的,因此,最简单的获取子串的方式就是截取String.characters,得到一个新的CharacterView,并用这个view,生成新的String对象。例如,我们要截取mixStr中的“interesting”部分,可以这样:
let swiftView = mixStr.characters.suffix(12).dropLast()
String(swiftView) // interesting
这样,我们先用suffix截掉了头部的"Swift 3.0 is",再用dropLast方法去掉了末尾的“!”,但别忘了,此时,我们针对mixStr.characters的操作,得到的是一个String.CharacterView对象,我们需要用这个view,生成一个新的String。
另外一类和子串相关的操作就是按照一定规则把之前的字符分割成多个部分,先来看个例子:
let strViews = mixStr.characters.split(separator: " ")
strViews.map(String.init)
// ["Swift", "3.0", "is", "interesting!"]
其中,我们可以把strViews理解为一个String.CharacterView集合。然后用map方法把每集合中的每一个view都生成一个新的String对象,最后,就得到了一个包含每一个子串的数组Array<String>。
除了用特定字符来分割子串,我们还可以用一个closure来指定分割条件。例如,把mixStr中的每个奇数位置的字符当成分隔符:
var i = 0
let singleCharViews = mixStr.characters.split { _ in
if i > 0 {
i = 0
return true
}
else {
i += 1
return false
}
}
singleCharViews.map(String.init)
// ["S", "i", "t", "3", "0", "i", " ", "n", "e", "e", "t", "n", "!"]
网友评论