Swift教程之字符串和字符详解
一个字符串String就是一个字符序列,像”hello,world”,”albatross”这样的。Swift中的字符串是用String关键词来定义的,同时它也是一些字符的集合,用Character定义。
Swift的String和Character类型为代码提供了一个快速的,兼容Unicode的字符解决方案。String类型的初始化和使用都是可读的,并且和C中的strings类似。同时String也可以通过使用+运算符来组合,使用字符串就像使用Swift中的其他基本类型一样简单。
1、字符串常量
在代码中可以使用由String预先定义的字符串常量,定义方式非常简单:
letsomeString=“Somestringliteralvalue”
字符串常量可以包括下面这些特殊字符:
空字符\0,反斜杠\,制表符\t,换行符\n,回车符\r,双引号\”和单引号\'
单字节Unicode字符,\xnn,其中nn是两个十六进制数
双字节Unicode字符,\unnnn,其中nnnn是四个十六进制数
四字节Unicode字符,\Unnnnnnnn,其中nnnnnnnn是八个十六进制数
下面的代码给出了这四种字符串的例子:
letwiseWords="\"Imaginationismoreimportantthanknowledge\"-Einstein" //"Imaginationismoreimportantthanknowledge"-Einstein letdollarSign="\x24"//$,UnicodescalarU+0024 letblackHeart="\u2665"//♥,UnicodescalarU+2665 letsparklingHeart="\U0001F496"//,UnicodescalarU+1F496
2、初始化一个空串
初始化一个空串时有两种形式,但是两种初始化方法的结果都一样,表示空串
varemptyString=""//emptystringliteral varanotherEmptyString=String()//initializersyntax //thesetwostringsarebothempty,andareequivalenttoeachother
通过isEmpty属性可以检查一个字符串是否为空
ifemptyString.isEmpty{ println("Nothingtoseehere") } //prints"Nothingtoseehere"
3、变长字符串
如果使用var关键词定义的字符串即为可修改的变长字符串,而let关键词定义的字符串是常量字符串,不可修改。
varvariableString="Horse" variableString+="andcarriage" //variableStringisnow"Horseandcarriage" letconstantString="Highlander" constantString+="andanotherHighlander" //thisreportsacompile-timeerror-aconstantstringcannotbemodified
4、字符串不是指针,而是实际的值
在Swift中,一个String类型就是一个实际的值,当定义一个新的String,并且将之前的String值拷贝过来的时候,是实际创建了一个相等的新值,而不是仅仅像指针那样指向过去。
同样在函数传递参数的时候,也是传递的实际值,并且创建了一个新的字符串,后续的操作都不会改变原有的String字符串。
5、字符
Swift的字符串String就是由字符Character组成的,每一个Character都代表了一个特定的Unicode字符。通过for-in循环,可以遍历字符串中的每一个字符:
forcharacterin"Dog!"{ println(character) } //D //o //g //! //
你也可以仅仅定义一个单独的字符:
letyenSign:Character="¥"
6、字符计数
使用全局函数countElements可以计算一个字符串中字符的数量:
letunusualMenagerie="Koala,Snail,Penguin,Dromedary" println("unusualMenageriehas\(countElements(unusualMenagerie))characters") //prints"unusualMenageriehas40characters"
7、组合使用字符和字符串
String和Character类型可以通过使用+号相加来组合成一个新的字符串
letstring1="hello" letstring2="there" letcharacter1:Character="!" letcharacter2:Character="?" letstringPlusCharacter=string1+character1//equals"hello!" letstringPlusString=string1+string2//equals"hellothere" letcharacterPlusString=character1+string1//equals"!hello" letcharacterPlusCharacter=character1+character2//equals"!?"
也可以使用+=号来组合:
varinstruction="lookover" instruction+=string2 //instructionnowequals"lookoverthere" varwelcome="goodmorning" welcome+=character1 //welcomenowequals"goodmorning!"
8、使用字符串生成新串
通过现有的字符串,可以使用如下方法来生成新的字符串:
letmultiplier=3 letmessage="\(multiplier)times2.5is\(Double(multiplier)*2.5)" //messageis"3times2.5is7.5"
在上面这个例子中,首先使用multiplier这个字符串3,来作为新串的一部分,用(multiplier)添加,同时上面的例子还用到了类型转换Double(multiplier),将计算结果和字符串本身都作为元素添加到了新的字符串中。
9、字符串比较
Swift提供三种方法比较字符串的值:字符串相等,前缀相等,和后缀相等
字符串相等
当两个字符串的包含完全相同的字符时,他们被判断为相等。
letquotation="We'realotalike,youandI." letsameQuotation="We'realotalike,youandI." ifquotation==sameQuotation{ println("Thesetwostringsareconsideredequal") } //prints"Thesetwostringsareconsideredequal" //输出”Thesetwostringsareconsideredequal”
前缀(prefix)相等和后缀(hasSuffix)相等
使用string类的两个方法hasPrefix和hasSuffix,来检查一个字符串的前缀或者后缀是否包含另外一个字符串,它需要一个String类型型的参数以及返回一个布尔类型的值。两个方法都会在原始字符串和前缀字符串或者后缀字符串之间做字符与字符之间的。
下面一个例子中,用一个字符串数组再现了莎士比亚的罗密欧与朱丽叶前两幕的场景。
letromeoAndJuliet=[ "Act1Scene1:Verona,Apublicplace", "Act1Scene2:Capulet'smansion", "Act1Scene3:AroominCapulet'smansion", "Act1Scene4:AstreetoutsideCapulet'smansion", "Act1Scene5:TheGreatHallinCapulet'smansion", "Act2Scene1:OutsideCapulet'smansion", "Act2Scene2:Capulet'sorchard", "Act2Scene3:OutsideFriarLawrence'scell", "Act2Scene4:AstreetinVerona", "Act2Scene5:Capulet'smansion", "Act2Scene6:FriarLawrence'scell" ]
你可以使用hasPrefix方法和romeoAndJuliet数组计算出第一幕要表演多少个场景。
varact1SceneCount=0 forsceneinromeoAndJuliet{ ifscene.hasPrefix("Act1"){ ++act1SceneCount } } println("Thereare\(act1SceneCount)scenesinAct1") //输出”Thereare5scenesinAct1”
同理,使用hasSuffix方法去计算有多少个场景发生在Capulet公馆和FriarLawrence牢房
varmansionCount=0 varcellCount=0 forsceneinromeoAndJuliet{ ifscene.hasSuffix("Capulet'smansion"){ ++mansionCount }elseifscene.hasSuffix("FriarLawrence'scell"){ ++cellCount } } println("\(mansionCount)mansionscenes;\(cellCount)cellscenes") //输出"6mansionscenes;2cellscenes”
大小写字符串
你可以从一个String类型的uppercaseString和lowercaseString中获得一个字符串的大写或小写。
letnormal="Couldyouhelpme,please?" letshouty=normal.uppercaseString //shoutyisequalto"COULDYOUHELPME,PLEASE?" letwhispered=normal.lowercaseString //whisperedisequalto"couldyouhelpme,please?"
10、Unicode
Unicode是编码和表示文本的国际标准。它几乎可以显示所有语言的所有字符的标准形态。还可以从类似于文本文件或者网页这样的外部源文件中读取和修改他们的字符。
Unicode术语
每一个Unicode字符都能被编码为一个或多个unicodescalar。一个unicodescalar是一个唯一的21位数(或者名称),对应着一个字符或者标识。例如U+0061是一个小写的A(“a”),或者U+1F425是一个面向我们的黄色小鸡
当一个Unicode字符串写入文本或者其他储存时,unicodescalar会根据Unicode定义的格式来编码。每一个格式化编码字符都是小的代码块,称成为codeunits.他包含UTF-8格式(每一个字符串由8位的codeunits组成)。和UTF-16格式(每一个字符串由16位的codeunits组成)
Unicode字符串
Swift支持多种不同的方式取得Unicode字符串.
你可以使用for-in语句遍历字符串,来获得每一个字符的Unicode编码值。这个过程已经在字符(WorkingwithCharacters)描述过了。
或者,下面三个描述中使用合适的一个来获得一个字符串的值
UTF-8字符编码单元集合使用String类型的utf-8属性
UTF-16字符编码单元集合使用String类型的utf-16属性
21位Unicode标量集合使用String类型的unicodeScalars属性
下面的每一个例子展示了不同编码显示由D,o,g,!
(DOGFACE,或者Unicode标量U+1F436)字符组成的字符串
UTF-8
你可以使用String类型的utf8属性遍历一个UTF-8编码的字符串。这个属性是UTF8View类型
,UTF8View是一个8位无符号整形(UInt8)的集合,集合中的每一个字节都是UTF-8编码。
forcodeUnitindogString.utf8{ print("\(codeUnit)") } print("\n") //6811110333240159144182
在上面的例子中,前4个十进制codeunit值(68,111,103,33)显示为字符串D,o,g和!,和他们的ASCII编码相同一样。后面4个codeunit的值(240,159,144,182)是DOGFACE字符的4字节UTF-8编码。
UTF-16
你可以使用String类型的utf16属性遍历一个UTF-16编码的字符串。这个属性是UTF16View类型,UTF16View是一个16位无符号整形(UInt16)的集合,集合中的每一个字节都是UTF-16编码。
forcodeUnitindogString.utf16{ print("\(codeUnit)") } print("\n") //68111103335535756374
同理,前4个十进制codeunit值(68,111,103,33)显示为字符串D,o,g和!,他们的UTF-16的codeunit和他们UTF-8的编码值相同。
第5和第6个codeunit值(55357和56374)是DOGFACE字符的UTF-16的代理对编码。他们的值是由值为U+D83D(十进制55357)的高位代理(leadsurrogate)和值为U+DC36(十进制56374)的低位代理(trailsurrogate)组成。
Unicode标量
你可以使用String类型的unicodeScalars属性遍历一个Unicode标量编码的字符串。这个属性是UnicodeScalarsView类型,UnicodeScalarsView是一个UnicodeScalar类型的集合。每一个Unicode标量都是一个任意21位Unicode码位,没有高位代理,也没有低位代理。
每一个UnicodeScalar使用value属性,返回标量的21位值,每一位都是32位无符号整形(UInt32)的值:
forscalarindogString.unicodeScalars{ print("\(scalar.value)") } print("\n") //6811110333128054
value属性在前4个UnicodeScalar值(68,111,103,33)再一次展示编码了字符D,o,g和!。第五个也是最后一个UnicodeScalar是DOGFACE字符,十进制为128054,等价于16进制的1F436,相当于Unicode标量的U+1F436。
每一个UnicodeScalar可以被构造成一个新的字符串来代替读取他们的value属性,类似于插入字符串。
forscalarindogString.unicodeScalars{println("\(scalar)")} //D //o //g //! //