Swift 字符串速查表

链接:http://www.cocoachina.com/swift/20151218/14746.html

字符串初始化

创建一个字符串对象有无数种方式可以使用,包括字面量、从其他 Swift 类型转换、Unicode等等。

var emptyString = ""  *// 空字符串*
var stillEmpty = **String**() *// 另一种空字符串的形式*
let helloWorld = "Hello World!" *// 字符串字面量*
let a = **String**(true) *// 由布尔值转换为:"true"*
let b: Character = "A" *// 显式创建一个字符类型*
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)")     *// "Hellon"*

字符串检测(空值、等值以及次序)

检测一个字符串是否为空:

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" 前缀/后缀检测检测一个字符串是否拥有某个前缀或者后缀:

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 就变得极其有用:

successor():获取下一个元素
predecessor():获取上一个元素
advancedBy(n):向前或者向后跳 n 个元素

下面是一些用例,注意到如果必要的话你可以将操作串联起来:

cafe[cafe.startIndex]                         *// "c"*
cafe[cafe.startIndex.successor()]             *// "a"*
cafe[cafe.startIndex.successor().successor()] *// "f"*
*// 注意到 cafe[endIndex] 会引发运行时错误*
cafe[cafe.endIndex.predecessor()]             *// "é"*
cafe[cafe.startIndex.advancedBy(2)]           *// "f"*

Indices 属性将返回字符串中所有元素的范围,这在遍历集合的时候很有用:

for index in cafe.characters.indices {
  print(cafe[index])
}

你无法使用某个字符串中的索引来访问另一个字符串。你可以通过 distanceTo 方法将索引转换为整数值:

let word1 = "ABCDEF"
let word2 = "012345"
let indexC = word1.startIndex.advancedBy(2)
let distance = word1.startIndex.distanceTo(indexC) *// 2*
let digit = word2[word2.startIndex.advancedBy(distance)] *// "2"*

范围的使用

要检出字符串集合中某个范围内的元素的话,可以使用范围。范围可以通过 start 和 end 索引来完成创建:'

let fqdn = "useyourloaf.com"
let rangeOfTLD = **Range**(start: fqdn.endIndex.advancedBy(-3), 
                         end: fqdn.endIndex)
let tld = fqdn[rangeOfTLD] *// "com"*

使用 “…” 或者 “..


通过索引或者范围来截取字符串

要通过索引或者范围来截取字符串的话,有许多方法:

获取前缀或者后缀

如果你需要得到或者抛弃字符串前面或者后面的某些元素的话,可以:

let digits = "0123456789"
let tail = **String**(digits.characters.dropFirst())  *// "123456789"*
let less = **String**(digits.characters.dropFirst(3)) *// "23456789"*
let head = **String**(digits.characters.dropLast(3))  *// "0123456"*
 
let prefix = **String**(digits.characters.prefix(2))  *// "01"*
let suffix = **String**(digits.characters.suffix(2))  *// "89"*
 
let index4 = digits.startIndex.advancedBy(4)
let thru4 = **String**(digits.characters.prefixThrough(index4)) *// "01234"*
let upTo4 = **String**(digits.characters.prefixUpTo(index4))    *// "0123"*
let from4 = **String**(digits.characters.suffixFrom(index4))    *// "456789"*

插入或删除

要在指定位置插入字符的话,可以通过索引:

var stars = "******"
stars.insert("X", atIndex: stars.startIndex.advancedBy(3))
*// "***X***"*

要在索引出插入字符串的话,那么需要将字符串转换为字符集:

stars.insertContentsOf("YZ".characters, at: stars.endIndex.advancedBy(-3))
*// "***XYZ***"*

范围替换

要替换一个范围的字符串内容的话:

添加元素

可以通过“+”运算符将字符串相互连接起来,也可以使用 appendContentsOf 方法:

var message = "Welcome"
message += " Tim" *// "Welcome Tim"*
message.appendContentsOf("!!!") *// "Welcome Tim!!!*

移除或者返回指定索引的元素

从一个字符串当中移除某个元素,需要注意这个方法将会使该字符串此前所有的任何索引标记(indice)失效。

var grades = "ABCDEF"
let ch = grades.removeAtIndex(grades.startIndex) *// "A"*
print(grades) *// "BCDEF"*

范围移除

移除字符集中某个范围的字符,需要主要的是这个方法同样也会使索引标记失效:

var sequences = "ABA BBA ABC"
let midRange = sequences.startIndex.advancedBy(4)...sequences.endIndex.advancedBy(-4)
sequences.removeRange(midRange)  *// "ABA ABC"*

与 NSString 桥接

String 可以转换为 NSString 从而与 Objective-C 桥接。如果 Swift 标准库没有你所需要的功能的话,那么导入 Foundation 框架,通过 NSString 来访问这些你所需要的方法。

请注意这个桥接方法并不是无损的,因此尽可能使用 Swift 标准库完成大部分功能。

// 不要忘记导入 Foundation*
import **Foundation**
let welcome = "hello world!"
welcome.capitalizedString     *// "Hello World!"*

检索内含的字符串

使用 NSString 方法的一个例子就是执行内含字符串的检索:

let text = "123045780984"
**if** let rangeOfZero = text.rangeOfString("0",
       options: NSStringCompareOptions.**BackwardsSearch**) {
  *// 寻找“0”元素,然后获取之后的元素*
  let suffix = **String**(text.characters.suffixFrom(rangeOfZero.endIndex)) *// "984"*
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容