Swift中String和Character的使用与总结


我博客原文: http://zyden.vicp.cc/string-character/
欢迎转载,请注明出处,谢谢

使用String字面量给常量赋值

let string = "string literal value"

常量string将会自动推断为String类型


初始化一个空的String

var emptyStr = ""              //使用空字符串字面量
var anotherEmptyStr = String() //使用构造方法
//两者没有区别

使用isEmpty判断空String:

if emptyStr.isEmpty {
    print("have nothing here")
}


String的可变性

使用“+”连接字符串,当然也支持自加运算符"+="

var variableStr = "LastName"
variableStr += "and FirstName"
/// variableStr is "LastName and FirstName"

//**but if:
let constantStr = "Gender"
constantStr += "and another Highlander"
///编译器会报错,被声明为常量的字符串不能被修改!

跟oc不同,swift的String通过var/let 变量/常量 标识决定其是否可变(can be mutated),而不需要选择NSString 还是 NSMutableString。

<br >

String是值类型

区别引用类型,在String在方法间传递,或者将其赋值给一个常量或者变量时,该String将会被复制(copy),而不是指向原来的对象。


String跟Characters的连接

let str = "hello world "
let char: Character = "!"
str.append(char)
// 结果str为: "hello world !"


遍历String

for char in "myStr".characters {
    print(char)
}
//m
//y
//S
//t
//r


字符串插值

在字符串中插入常量变量表达式等,构造一个新的字符串"通过()":

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)" 
/// message is "3 times 2.5 is 7.5"


String中使用转义字符

在字符串中输入反斜线”\” 水平制表符”t” 换行”n” 双引号”“” 单引号”’” 等都需要在前面添加”\”进行转义,同时可以在转义字符后添加Unicode来进行特殊符号表情的显示:

//**双引号转义
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
///"Imagination is more important than knowledge" - Einstein

//**Unicode转义
let dollarSign = "\u{24}"        // $,  Unicode scalar U+0024
let blackHeart = "\u{2665}"      // ♥,  Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // ��, Unicode scalar U+1F496

//**扩展自行集
//**对应关系
//  \u{D55C}----한
//  \u{1112}----ᄒ
//  \u{1161}----ᅡ
//  \u{11AB}----ᆫ
let KoreaStr = "\u{D55C}\u{1112}\u{1161}\u{11AB}" //한한 


String长度

string.characters.count

let str = "1234567890"
print("str has \(str.characters.count) characters")
//输出 "star has 10 characters"

//**为String增加笔画不会造成长度增加:
var str = "cafe"
print("the number of characters in \(word) is \(word.characters.count)")
// 输出 "the number of characters in cafe is 4"
//**now append some Unicode:
word += "\u{301}"
print("the number of characters in \(word) is \(word.characters.count)")
//输出 "the number of characters in café is 4"
//仅仅是改变了最后一个字符,并没有增加字符串的长度

正因为swift支持扩展字形集,不同的字符,和相同的不同表示的字符可能需要不同量的存储器来存储,所以在swift中characters所占用的存储量是不一定相同的,因此不能像oc计算NSString那样使用字符串来迭代计算,而应该遍历字符串的characters来确定字符串的长度。


访问和修改字符串

可以通过其方法和属性,或者下标,来访问或者修改字符串

字符串索引
swift中的字符串具有相关连的索引类型(String.Index),可对应其每个位置的Character

正如上面所说,不同的字符串可能需要不同数量的内存来存储,所以为了确定哪些character在特定的位置上,我们必须遍历确定每个Unicode的开始结束位置,因此,String不能使用整形作索引。

startIndex: 访问String第一个位置的字符
endIndex: 访问String最后一个位置的字符
(一个空的字符串或者长度为1的字符串,startIndex和endIndex相等)

predecessor(), successor(), advancedBy()
一个String.Index值可以通过调用predecessor()方法来访问其前一个index, 调用successor()来访问其后一个index, 或者调用advancedBy()来指定访问相对位置的index( 之后5位的index: advancedBy(5) 往前5位的index: advancedBy(-5) )

let greeting = "Guten Tag!"
greeting[greeting.startIndex]
//G
greeting[greeting.endIndex.predecessor()]
//!
greeting[greeting.startIndex.successor()]
//u
let index = greeting.startIndex.advancedBy(7)
//a
greeting[index]
//输出 a

indiced : 字符串Index的集合

for index in greeting.characters.indices {
    print("\(greeting[index])", terminator: " ")
}
///prints "G u t e n  T a g !"


插入/移除

利用index,在制定位置插入字符character

var helloStr = "hello"
helloStr.insert("~", atIndex: helloStr.endIndex)
// hello~

同理,插入字符串(字符的集合)

var helloStr = "hello!"
helloStr.insertContentOf(" world!".characters, at: hello.endIndex)
// hello! world

//用上面的知识,再追求下完美:
var helloStr = "hello!"
helloStr.insertContentOf(" world".characters, at: hello.endIndex.predecessor())
// hello world!

移除(index):

var helloStr = "hello world!"
helloStr.removeAtIndex(helloStr.endIndex.predecessor())
// hello world
//注意:
// endIndex是指最后一个index位(将要输入内容的index位)
//所以删除最后一个字符使用的index是endIndex.predecessor()(将要输入内容的index的前一个index位)
//而不是endIndex

移除(Range):

var helloStr = "hello world!"
let range = Range(start: helloStr.endIndex.advancedBy(-6), end: helloStr.endIndex.predecessor())
// 顺便贴一个new Range的简易写法:
// let range = helloStr.endIndex.advancedBy(-6)..<helloStr.endIndex
// 效果是一样的
helloStr.removeRange(range)
// hello


字符串比较

两个纯字符串比较

let oneStr = "We're a lot alike, you and I."
let anotherStr = "We're a lot alike, you and I."

if oneStr == anotherStr {
    print("These two strings are considered equal")
}
//输出: These two strings are considered equal
//相等

两个由characters组成的字符串比较

let oneStr = "Voulez-vous un caf\u{E9}?"
//Voulez-vous un café?
let anotherStr = "Voulez-vous un caf\u{65}\u{301}?"
//Voulez-vous un café?
//两者虽然看起来内容字符不同,其实\u{65}\u{301}是一个e和一个音调符号,根据上面的知识,结果组合成é(\u{E9})

if oneStr == anotherStr {
    print("These two strings are considered equal")
}
//输出: These two strings are considered equal
//相等

两个表现相同的character比较

let oneChar: Character = "\u{41}"
//拉丁字母中的A
let anotherChar: Character = "\u{0410}"
//西里尔字母中的A

if oneChar != anotherChar {
    print(These two characters are not equivalent)
}
//输出: These two characters are not equivalent
//不相等!

前缀和后缀的比较
我们可以使用hasPrefix()方法和hasSuffix()去匹配String的前缀和后缀,并返回一个Boolean值

let romeoAndJuliet = [
    "Act 1 Scene 1: Verona, A public place",
    "Act 1 Scene 2: Capulet's mansion",
    "Act 1 Scene 3: A room in Capulet's mansion",
    "Act 1 Scene 4: A street outside Capulet's mansion",
    "Act 1 Scene 5: The Great Hall in Capulet's mansion",
    "Act 2 Scene 1: Outside Capulet's mansion",
    "Act 2 Scene 2: Capulet's orchard",
    "Act 2 Scene 3: Outside Friar Lawrence's cell",
    "Act 2 Scene 4: A street in Verona",
    "Act 2 Scene 5: Capulet's mansion",
    "Act 2 Scene 6: Friar Lawrence's cell"
]
//----遍历这个字符数组,匹配下前缀看看效果
var count = 0
for str in romeoAndJuliet {
    if str.hasPrefix("Act 1 ") {
        count++
    }
}
print("There are \(count) string with Act 1 ")
// 输出: "There are 5 string with Act 1"

//----后缀呢
var count = 0
for str in romeoAndJuliet {
    if str.hasSuffix("Capulet's mansion") {
        count++
    } 
}
print("There are \(count) mansion string")
// 输出: "There are 6 mansion stressing"


String使用UTF-8编码表示

复习一下,上面也提到,Swift中的String支持emoji表情和众多特殊字符,这也是String一个单位长度不一定等于两个character(汉字)或者1个character(英文字母)的原因。
先回到我们的话题。String和UTF-8的对应关系,我们来看一张官方电子书中的表:
![]/content/images/2015/12/utf8.png()

//上图中对应的String:
//let dogString = "Dog!!��"

//同时String中的UTF-8编码也是可以像char那样遍历的
for unitCode in dogString.utf8 {
    print("\(unitCode) ", terminator: "")
}
//输出: 68 111 103 226 128 188 240 159 144 182

同理String也可以以UTF-16 和Unicode的方式遍历

for unitCode in dogString.utf16 {
}

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")
}
// 68 111 103 8252 128054

for scalar in dogString.unicodeScalars {
    print("\(scalar) ", terminator: "")
}
// D o g !! ��

//注意: 直接printunicodeScalar的话跟String的输出是一样效果的
//我们print出他的value,才是我们想要的编码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容