Swift Strings and Characters

Initializing an Empty String

To create an empty String
value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String
instance with initializer syntax:

var emptyString = "" // empty string literal

var anotherEmptyString = String() // initializer syntax

// these two strings are both empty, and are equivalent to each other

Find out whether a String
value is empty by checking its Boolean isEmpty
property:

if emptyString.isEmpty {

print("Nothing to see here")

}

// Prints "Nothing to see here"

Find out whether a String
value is empty by checking its Boolean isEmpty
property:

if emptyString.isEmpty {

print("Nothing to see here")

}

// Prints "Nothing to see here"

String Mutability

You indicate whether a particular String
can be modified (or mutated) by assigning it to a variable (in which case it can be modified), or to a constant (in which case it cannot be modified):

var variableString = "Horse"

variableString += " and carriage"

// variableString is now "Horse and carriage"

let constantString = "Highlander"

constantString += " and another Highlander"

// this reports a compile-time error - a constant string cannot be modified

Working with Characters

You can access the individual Character
values for a String
by iterating over its characters
property with a for
-in
loop:

for character in "Dog!

🐶
".characters {

print(character)

}

// D

// o

// g

// !

// 

🐶

The for
-in
loop is described in For-In Loops.
Alternatively, you can create a stand-alone Character
constant or variable from a single-character string literal by providing a Character
type annotation:

let exclamationMark: Character = "!"

String
values can be constructed by passing an array of Character
values as an argument to its initializer:

let catCharacters: [Character] = ["C", "a", "t", "!", "

🐱
"]

let catString = String(catCharacters)

print(catString)

// Prints "Cat!

🐱
"
let exclamationMark: Character = "!"
let catCharacters: [Character] = ["C", "a", "t", "!", "

🐱
"]

let catString = String(catCharacters)

print(catString)

// Prints "Cat!

🐱
"

Concatenating Strings and Characters

String
values can be added together (or concatenated) with the addition operator (+) to create a new String value:

let string1 = "hello"

let string2 = " there"

var welcome = string1 + string2

// welcome now equals "hello there"

You can also append a String
value to an existing String
variable with the addition assignment operator (+=):

var instruction = "look over"

instruction += string2

// instruction now equals "look over there"

You can append a Character
value to a String
variable with the String
type’s append()
method:

let exclamationMark: Character = "!"

welcome.append(exclamationMark)

// welcome now equals "hello there!"

String Interpolation

String interpolation is a way to construct a new String
value from a mix of constants, variables, literals, and expressions by including their values inside a string literal. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash:

let multiplier = 3

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

// message is "3 times 2.5 is 7.5"

In the example above, the value of multiplier
is inserted into a string literal as (multiplier)
. This placeholder is replaced with the actual value of multiplier
when the string interpolation is evaluated to create an actual string.
The value of multiplier
is also part of a larger expression later in the string. This expression calculates the value of Double(multiplier) * 2.5
and inserts the result (7.5
) into the string. In this case, the expression is written as (Double(multiplier) * 2.5)
when it is included inside the string literal.

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"

// "Imagination is more important than knowledge" - Einstein

let dollarSign = "\u{24}" // $, Unicode scalar U+0024

let blackHeart = "\u{2665}" // ♥, Unicode scalar U+2665

let sparklingHeart = "\u{1F496}" // 💖, Unicode scalar U+1F496

Extended Grapheme Clusters

Every instance of Swift’s Character
type represents a single extended grapheme cluster. An extended grapheme cluster is a sequence of one or more Unicode scalars that (when combined) produce a single human-readable character.
Here’s an example. The letter é
can be represented as the single Unicode scalar é
(LATIN SMALL LETTER E WITH ACUTE
, or U+00E9
). However, the same letter can also be represented as a pair of scalars—a standard letter e
(LATIN SMALL LETTER E
, or U+0065
), followed by the COMBINING ACUTE ACCENT
scalar (U+0301
). The COMBINING ACUTE ACCENT
scalar is graphically applied to the scalar that precedes it, turning an e
into an é
when it is rendered by a Unicode-aware text-rendering system.
In both cases, the letter é
is represented as a single Swift Character
value that represents an extended grapheme cluster. In the first case, the cluster contains a single scalar; in the second case, it is a cluster of two scalars:

let eAcute: Character = "\u{E9}" // é

let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ́

// eAcute is é, combinedEAcute is é

Extended grapheme clusters are a flexible way to represent many complex script characters as a single Character
value. For example, Hangul syllables from the Korean alphabet can be represented as either a precomposed or decomposed sequence. Both of these representations qualify as a single Character
value in Swift:

let precomposed: Character = "\u{D55C}" // 한

let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // ᄒ, ᅡ, ᆫ

// precomposed is 한, decomposed is 한

Extended grapheme clusters enable scalars for enclosing marks (such as COMBINING ENCLOSING CIRCLE
, or U+20DD
) to enclose other Unicode scalars as part of a single Character
value:

let enclosedEAcute: Character = "\u{E9}\u{20DD}"

// enclosedEAcute is é⃝

Unicode scalars for regional indicator symbols can be combined in pairs to make a single Character
value, such as this combination of REGIONAL INDICATOR SYMBOL LETTER U
(U+1F1FA
) and REGIONAL INDICATOR SYMBOL LETTER S
(U+1F1F8
):

let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"

// regionalIndicatorForUS is 🇺🇸

Counting Characters

To retrieve a count of the Character
values in a string, use the count
property of the string’s characters
property:

let unusualMenagerie = "Koala 🐨, Snail 🐌, Penguin 🐧, Dromedary 🐪"

print("unusualMenagerie has \(unusualMenagerie.characters.count) characters")

// Prints "unusualMenagerie has 40 characters"

Note that Swift’s use of extended grapheme clusters for Character
values means that string concatenation and modification may not always affect a string’s character count.
For example, if you initialize a new string with the four-character word cafe
, and then append a COMBINING ACUTE ACCENT
(U+0301
) to the end of the string, the resulting string will still have a character count of 4
, with a fourth character of é
, not e
:

var word = "cafe"

print("the number of characters in \(word) is \(word.characters.count)")

// Prints "the number of characters in cafe is 4"

word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301

print("the number of characters in \(word) is \(word.characters.count)")

// Prints "the number of characters in café is 4"

Accessing and Modifying a String

You access and modify a string through its methods and properties, or by using subscript syntax.
String Indices
Each String
value has an associated index type, String.Index
, which corresponds to the position of each Character
in the string.
As mentioned above, different characters can require different amounts of memory to store, so in order to determine which Character
is at a particular position, you must iterate over each Unicode scalar from the start or end of that String
. For this reason, Swift strings cannot be indexed by integer values.
Use the startIndex
property to access the position of the first Character
of a String
. The endIndex
property is the position after the last character in a String
. As a result, the endIndex
property isn’t a valid argument to a string’s subscript. If a String
is empty, startIndex
and endIndex
are equal.
You access the indices before and after a given index using the index(before:)
and index(after:)
methods of String
. To access an index farther away from the given index, you can use the index(_:offsetBy:)
method instead of calling one of these methods multiple times.
You can use subscript syntax to access the Character
at a particular String
index.

let greeting = "Guten Tag!"

greeting[greeting.startIndex]

// G

greeting[greeting.index(before: greeting.endIndex)]

// !

greeting[greeting.index(after: greeting.startIndex)]

// u

let index = greeting.index(greeting.startIndex, offsetBy: 7)

greeting[index]

// a

Attempting to access an index outside of a string’s range or a Character
at an index outside of a string’s range will trigger a runtime error.

greeting[greeting.endIndex] // Error

greeting.index(after: greeting.endIndex) // Error

Use the indices

property of the characters
property to access all of the indices of individual characters in a string.

for index in greeting.characters.indices {

print("\(greeting[index]) ", terminator: "")

}

// Prints "G u t e n T a g ! "

Inserting and Removing

To insert a single character into a string at a specified index, use the insert(_:at:)
method, and to insert the contents of another string at a specified index, use the insert(contentsOf:at:)
method.

var welcome = "hello"

welcome.insert("!", at: welcome.endIndex)

// welcome now equals "hello!"

welcome.insert(contentsOf:" there".characters, at: welcome.index(before: welcome.endIndex))

// welcome now equals "hello there!"

To remove a single character from a string at a specified index, use the remove(at:)
method, and to remove a substring at a specified range, use the removeSubrange(_:)
method:

welcome.remove(at: welcome.index(before: welcome.endIndex))

// welcome now equals "hello there"

let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex

welcome.removeSubrange(range)

// welcome now equals "hello"

String and Character Equality

String and character equality is checked with the “equal to” operator (==
) and the “not equal to” operator (!=
), as described in Comparison Operators:

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

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

if quotation == sameQuotation {

print("These two strings are considered equal")

}

// Prints "These two strings are considered equal"

Prefix and Suffix Equality

To check whether a string has a particular string prefix or suffix, call the string’s hasPrefix(:)
and hasSuffix(
:)
methods, both of which take a single argument of type String
and return a Boolean value.
The examples below consider an array of strings representing the scene locations from the first two acts of Shakespeare’s Romeo and Juliet:

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"

]

You can use the hasPrefix(_:)
method with the romeoAndJuliet
array to count the number of scenes in Act 1 of the play:
var act1SceneCount = 0

for scene in romeoAndJuliet {

if scene.hasPrefix("Act 1 ") {

act1SceneCount += 1

}

}

print("There are \(act1SceneCount) scenes in Act 1")

// Prints "There are 5 scenes in Act 1"

Similarly, use the hasSuffix(_:)
method to count the number of scenes that take place in or around Capulet’s mansion and Friar Lawrence’s cell:

var mansionCount = 0

var cellCount = 0

for scene in romeoAndJuliet {

if scene.hasSuffix("Capulet's mansion") {

mansionCount += 1

} else if scene.hasSuffix("Friar Lawrence's cell") {

cellCount += 1

}

}

print("\(mansionCount) mansion scenes; \(cellCount) cell scenes")

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

推荐阅读更多精彩内容