本文由CocoaChina译者星夜暮晨翻译
Swift 的字符串 API 似乎让人难以习惯。此外,每次 Swift 与其标准库版本更新的时候,字符串的 API 也时不时会发生改变。你在 Stack Overflow 上寻找到的 Swift 1.2 解决方案往往不能在 Swift 2 上按照预期(甚至完全不能)使用。虽然从好的方面来看,我发现苹果的官方文档是非常有用的(参见本文底部的链接),但是出于备查的目的以及为了帮助仍挣扎于其中的人们,在此我仍旧了列出一系列的 String 代码片段:
(Gist 和我 Github 仓库中的 Playground 都已提供)
字符串初始化
创建一个字符串对象有无数种方式可以使用,包括字面量、从其他 Swift 类型转换、Unicode等等。
var
emptyString =
""
// 空字符串
var
stillEmpty = String()
// 另一种空字符串的形式
let helloWorld =
"Hello World!"
// 字符串字面量
let a = String(
true
)
// 由布尔值转换为:"true"
let b: Character =
"A"
// 显式创建一个字符类型
@H_502_97@let c = String(b)
// 从字符 "A" 转换
let d = String(3.14)
// 从 Double 类型转换为 "3.14"
let e = String(1000)
// 从 Int 类型转换为 "1000"
let f =
"Result = \(d)"
// 字符串插值 "Result = 3.14"
let g =
"\u{2126}"
// Unicode 字符,欧米伽符号 Ω
let h = String(count:3,repeatedValue:b)
// 重复字符组成的字符串 "AAA"
字符串是值类型
字符串是值类型(Value Type),当用其赋值或者函数传参的时候它会被拷贝(copied)。所拷贝的值在修改的时候是懒加载的(lazy)。
var
aString =
"Hello"
var
bString = aString
bString +=
" World!"
// "Hello World!"
print(
"\(aString)"
)
// "Hello\n"
字符串检测(空值、等值以及次序)
检测一个字符串是否为空:
emptyString.isEmpty
// true
Swift 是支持 Unicode 编码的,因此相等运算符("==")将会判断 Unicode 的范式是否等价(canonical equivalence)。这意味着对于两个字符串来说,如果拥有相同的语义(linguistic meaning)和表现形式的话,即使它们由不同 Unicode 标量(scalar)组成,那么也认为这两个字符串相等:
let spain =
"Espa?a"
let tilde =
"\u{303}"
let country =
"Espan"
+
"\(tilde)"
+
"a"
if
country == spain {
print(
"满足匹配!"
)
// "满足匹配!\n"
}
比较次序的话:
if
"aaa"
<
"bbb"
{
print(
"aaa"
)
}
前缀/后缀检测
检测一个字符串是否拥有某个前缀或者后缀:
let line =
"0001 这里放上一些测试数据 %%%%"
line.hasPrefix(
"0001"
)
// true
line.hasSuffix(
"%%%%"
)
// true
大小写互相转换
顾名思义:
let mixedCase =
"AbcDef"
let upper = mixedCase.uppercaseString
// "ABCDEF"
let lower = mixedCase.lowercaseString
// "abcdef"
字符集合
字符串并不是某种编码的字符集合(collection views),但是它可以通过相应的属性为不同的编码形式提供所对应的字符集合。
country.characters
// characters
country.unicodeScalars
// Unicode scalar 21-bit codes
country.utf16
// UTF-16 编码
country.utf8
// UTF-8 编码
字符总数
字符串并没有一个直接的属性用以返回其包含的字符总数,因为字符总数只对特定的编码形式来说才有意义。因此,字符总数需要通过不同编码的字符集合来访问:
// spain = Espa?a
print(
"\(spain.characters.count)"
)
// 6
print(
"\(spain.unicodeScalars.count)"
)
// 6
print(
"\(spain.utf16.count)"
)
// 6
print(
"\(spain.utf8.count)"
)
// 7
使用索引来访问字符集合
每个字符集合都拥有“索引”,可以通过它来访问整个集合中的元素。这或许是在使用字符串过程中碰到的最大难点之一了。你不能使用下标语法来访问字符串中的任意元素(比如说string[5])。
要遍历某个集合中的所有元素的时候(从现在开始我都将使用 characters 集合),可以通过 for...in 循环来进行:
var
sentence =
"Never odd or even"
for
character
in
sentence.characters {
print(character)
}
每个集合都有两个实例属性,你可以在集合中使用它们来进行索引,就如同下标语法哪样:
startIndex:返回首个元素的位置,如果为空,那么和 endIndex 的值相同。
endIndex:返回字符串逾尾(past the end)的位置。
注意到如果使用 endIndex 的话,就意味着你不能直接将其作为下标来进行使用,因为这会导致越界。
let cafe =
"café"
cafe.startIndex
// 0
cafe.endIndex
// 4 - 最后一个字符之后的位置
当通过以下几种方法进行字符串修改的时候,startIndex 和 endIndex 就变得极其有用:
下面是一些用例,注意到如果必要的话你可以将操作串联起来:
cafe[cafe.startIndex]
// "c"
cafe[cafe.startIndex.successor()]
// "a"
cafe[cafe.startIndex.successor().successor()]
// "f"
// 注意到 cafe[endIndex] 会引发运行时错误
@H_502_97@cafe[cafe.endIndex.predecessor()]
// "é"
cafe[cafe.startIndex.advancedBy(2)]
// "f"