★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-pkdxqocj-er.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
甲串是一系列字符,如的或。Swift字符串由類型表示。能夠經過各類方式訪問a的內容,包括做爲值的集合。"hello, world"
"albatross"
String
String
Character
git
Swift String
和Character
類型提供了一種快速,符合Unicode的方式來處理代碼中的文本。字符串建立和操做的語法是輕量級和可讀的,字符串文字語法與C相似。字符串鏈接就像將兩個字符串與+
運算符組合同樣簡單,字符串可變性經過在常量或變量之間進行選擇來管理,就像Swift中的任何其餘值同樣。您還可使用字符串將常量,變量,文字和表達式插入到更長的字符串中,這一過程稱爲字符串插值。這樣能夠輕鬆地爲顯示,存儲和打印建立自定義字符串值。github
儘管語法簡單,但Swift的String
類型是一種快速,現代的字符串實現。每一個字符串都由與編碼無關的Unicode字符組成,並支持在各類Unicode表示中訪問這些字符。swift
注意api
Swift的String
類型與Foundation的NSString
類是橋接的。Foundation還擴展String
爲公開定義的方法NSString
。這意味着,若是您導入Foundation,則能夠NSString
在String
不進行強制轉換的狀況下訪問這些方法。數組
有關String
與Foundation和Cocoa一塊兒使用的更多信息,請參閱字符串和NSString之間的橋接。性能優化
您能夠String
在代碼中包含預約義值做爲字符串文字。字符串文字是由雙引號("
)包圍的字符序列。微信
使用字符串文字做爲常量或變量的初始值:app
須要注意的是斯威夫特,推測型String
的someString
,由於它有一個字符串值初始化不變。ide
若是須要跨越多行的字符串,請使用多行字符串文字 - 由三個雙引號括起來的字符序列:
多行字符串文字包括其開始和結束引號之間的全部行。該字符串從開始引號("""
)後面的第一行開始,到結束引號以前的行結束,這意味着下面的字符串都不會以換行符開頭或結尾:
當源代碼在多行字符串文字中包含換行符時,該換行符也會出如今字符串的值中。若是您想使用換行符來使源代碼更容易閱讀,可是您不但願換行符成爲字符串值的一部分,請在\
這些行的末尾寫一個反斜槓():
要建立以換行符開頭或結尾的多行字符串文字,請將空行寫爲第一行或最後一行。例如:
能夠縮進多行字符串以匹配周圍的代碼。在右引號mark("""
)以前的空格告訴Swift在全部其餘行以前要忽略哪些空格。可是,若是您在行的開頭寫入空格以及結束引號以前的空格,則包含該空格。
在上面的示例中,即便整個多行字符串文字是縮進的,字符串中的第一行和最後一行也不以任何空格開頭。中間線比縮進引號有更多的縮進,因此它從額外的四個空格縮進開始。
字符串文字能夠包含如下特殊字符:
\0
(空字符),\\
(反斜槓),\t
(水平製表符),\n
(換行符),\r
(回車符),\"
(雙引號)和\'
(單引號)\u{
Ñ}
,其中Ñ是一個1-8位十六進制數(統一在討論的Unicode下文)下面的代碼顯示了這些特殊字符的四個示例。該wiseWords
常數包含兩個逃脫雙引號。的dollarSign
,blackHeart
和sparklingHeart
常量展現Unicode標格式:
由於多行字符串文字使用三個雙引號而不是一個,因此您能夠"
在多行字符串文字中包含雙引號()而不轉義它。要將文本包含"""
在多行字符串中,請至少轉義其中一個引號。例如:
您能夠將字符串文字放在擴展分隔符中,以在字符串中包含特殊字符,而不調用它們的效果。您將字符串放在引號("
)中並用數字符號(#
)括起來。例如,打印字符串文字會打印換行符轉義序列(),而不是將字符串打印到兩行。#"Line 1\nLine 2"#
\n
若是須要字符串文字中字符的特殊效果,請匹配轉義字符(\
)後面的字符串中的數字符號數。例如,若是您的字符串是而且您想要中斷該行,則能夠改成使用。一樣,也打破了界限。#"Line 1\nLine 2"#
#"Line 1\#nLine 2"#
###"Line1\###nLine2"###
使用擴展分隔符建立的字符串文字也能夠是多行字符串文字。您可使用擴展分隔符將文本包含"""
在多行字符串中,從而覆蓋結束文字的默認行爲。例如:
要建立空String
值做爲構建更長字符串的起點,請將空字符串文字指定給變量,或String
使用初始化程序語法初始化新實例:
String
經過檢查其布爾isEmpty
屬性來肯定值是否爲空:
您String
能夠經過將特定分配給變量(在這種狀況下能夠修改)或常量(在這種狀況下不能修改)來指示特定是否能夠修改(或變異):
注意
這種方法不一樣於Objective-C和Cocoa中的字符串變異,您能夠在兩個類(NSString
和NSMutableString
)之間進行選擇,以指示字符串是否能夠變異。
Swift的String
類型是值類型。若是建立新String
值,則在將String
值傳遞給函數或方法時,或者將其賦值給常量或變量時,將複製該值。在每種狀況下,String
都會建立現有值的新副本,並傳遞或分配新副本,而不是原始版本。結構和枚舉是值類型中描述了值類型。
Swift的默認複製String
行爲可確保當函數或方法爲您傳遞一個String
值時,很明顯您擁有該確切的String
值,不管它來自何處。除非您本身修改,不然您能夠確信傳遞的字符串不會被修改。
在幕後,Swift的編譯器優化了字符串的使用,所以只有在絕對必要的狀況下才會進行實際的複製。這意味着在使用字符串做爲值類型時,您總能得到出色的性能。
您能夠經過使用- 循環遍歷字符串來訪問a的各個Character
值:String
for
in
的for
- in
環中描述對於-在循環中。
或者,您能夠Character
經過提供Character
類型註釋從單字符字符串文字建立獨立常量或變量:
String
能夠經過將Character
值數組做爲參數傳遞給其初始值設定項來構造值:
String
值能夠與加法運算符()一塊兒添加(或鏈接+
)以建立新String
值:
您還能夠使用加號賦值運算符()將String
值附加到現有String
變量+=
:
您能夠使用類型的方法將Character
值附加到String
變量:String
append()
注意
您不能將a String
或附加Character
到現有Character
變量,由於Character
值必須僅包含單個字符。
若是您使用多行字符串文字來構建較長字符串的行,則但願字符串中的每一行都以換行符結束,包括最後一行。例如:
在上面的代碼中,級聯badStart
與end
產生兩行字符串,這是不指望的結果。由於最後一行badStart
不以換行符結束,因此該行與第一行結合end
。相比之下,兩條線都goodStart
以一條換行結束,因此當它與end
結果結合時有三條線,正如預期的那樣。
字符串插值是一種String
經過在字符串文字中包含它們的值,從常量,變量,文字和表達式的混合構造新值的方法。您能夠在單行和多行字符串文字中使用字符串插值。插入到字符串文字中的每一個項目都包含在一對括號中,前綴爲反斜槓(\
):
在上面的示例中,值的值multiplier
插入到字符串文字中\(multiplier)
。此佔位符將替換multiplier
爲評估字符串插值以建立實際字符串時的實際值。
值multiplier
也是字符串中較大表達式的一部分。此表達式計算值,並將result()插入到字符串中。在這種狀況下,表達式被寫爲當它包含在字符串文字中時。Double(multiplier) * 2.5
7.5
\(Double(multiplier) * 2.5)
您可使用擴展字符串分隔符來建立包含字符的字符串,不然這些字符將被視爲字符串插值。例如:
要在使用擴展分隔符的字符串中使用字符串插值,請將反斜槓前面的數字符號數與字符串開頭和結尾處的數字符號數相匹配。例如:
注意
您在插值字符串內的括號內寫的表達式不能包含未轉義的反斜槓(\
),回車符或換行符。可是,它們能夠包含其餘字符串文字。
Unicode是用於在不一樣書寫系統中編碼,表示和處理文本的國際標準。它使您可以以標準化形式表示來自任何語言的幾乎任何字符,並從外部源(如文本文件或網頁)讀取和寫入這些字符。Swift String
和Character
類型徹底符合Unicode,如本節所述。
在幕後,Swift的原生String
類型是根據Unicode標量值構建的。Unicode標量值是字符或修飾符的惟一21位數字,例如U+0061
for ()或for ()。LATIN SMALL LETTER A
"a"
U+1F425
FRONT-FACING BABY CHICK
"🐥"
請注意,並不是全部21位Unicode標量值都分配給字符 - 某些標量保留用於未來分配或用於UTF-16編碼。已分配給一個字符標量值一般還具備一個名字,如和在上面的實施例。LATIN SMALL LETTER A
FRONT-FACING BABY CHICK
Swift Character
類型的每一個實例都表明一個擴展的字形集羣。擴展字形集羣是一個或多個Unicode標量的序列(當組合時)產生單我的類可讀字符。
這是一個例子。該字母é
能夠表示爲單個Unicode標量é
(,或)。可是,同一個字母也能夠表示爲一對標量 - 標準字母(,或),後跟標量()。該標量圖形應用到它前面,把一個標量到時它是由一個支持Unicode的文本的渲染系統渲染。LATIN SMALL LETTER E WITH ACUTE
U+00E9
e
LATIN SMALL LETTER E
U+0065
COMBINING ACUTE ACCENT
U+0301
COMBINING ACUTE ACCENT
e
é
在這兩種狀況下,字母é
都表示爲單個Swift Character
值,表示擴展的字形集羣。在第一種狀況下,集羣包含單個標量; 在第二種狀況下,它是兩個標量的集羣:
擴展的字形集羣是將許多複雜的腳本字符表示爲單個Character
值的靈活方式。例如,韓語字母表中的韓語音節能夠表示爲預先組合或分解的序列。這兩個表示都符合Character
Swift中的單個值:
擴展的字形集羣使標量能夠封閉標記(例如,或)以將其餘Unicode標量做爲單個值的一部分包含在內:COMBINING ENCLOSING CIRCLE
U+20DD
Character
區域指標符號的Unicode標量能夠成對組合以造成單個Character
值,例如()和()的這種組合:REGIONAL INDICATOR SYMBOL LETTER U
U+1F1FA
REGIONAL INDICATOR SYMBOL LETTER S
U+1F1F8
要檢索Character
字符串中值的計數,請使用字符串的count
屬性:
請注意,Swift將擴展字形集合用於Character
值意味着字符串鏈接和修改可能並不老是會影響字符串的字符數。
例如,若是使用四個字符的單詞初始化一個新字符串cafe
,而後在字符串的末尾附加一個(),則結果字符串的字符數仍爲第四個字符,而不是:COMBINING ACUTE ACCENT
U+0301
4
é
e
注意
擴展的字形集羣能夠由多個Unicode標量組成。這意味着不一樣的字符和相同字符的不一樣表示可能須要不一樣的內存量來存儲。所以,Swift中的字符不會在字符串表示中佔用相同數量的內存。所以,若是不迭代字符串以肯定其擴展的字形集羣邊界,則沒法計算字符串中的字符數。若是使用特別長的字符串值,請注意該count
屬性必須遍歷整個字符串中的Unicode標量,以肯定該字符串的字符。
count
屬性返回的字符數不老是與包含相同字符的length
屬性NSString
相同。a的長度NSString
基於字符串的UTF-16表示中的16位代碼單元的數量,而不是字符串中Unicode擴展的字形集羣的數量。
您能夠經過其方法和屬性或使用下標語法來訪問和修改字符串。
每一個String
值都有一個關聯的索引類型,String.Index
它對應Character
於字符串中每一個值的位置。
如上所述,不一樣的字符可能須要不一樣的內存量來存儲,所以爲了肯定哪一個Character
位於特定位置,您必須從開頭或結尾迭代每一個Unicode標量String
。所以,Swift字符串不能用整數值索引。
使用該startIndex
屬性訪問第Character
一個的位置String
。該endIndex
屬性是a中最後一個字符後的位置String
。所以,該endIndex
屬性不是字符串下標的有效參數。若是a String
是空的,startIndex
而且endIndex
是相等的。
您可使用index(before:)
和index(after:)
方法訪問給定索引以前和以後的索引String
。要訪問遠離給定索引的索引,可使用該index(_:offsetBy:)
方法而不是屢次調用其中一種方法。
您可使用下標語法來訪問Character
特定String
索引。
嘗試訪問字符串範圍Character
以外的索引或字符串範圍以外的索引將觸發運行時錯誤。
使用該indices
屬性能夠訪問字符串中單個字符的全部索引。
注意
您可使用startIndex
與endIndex
屬性和index(before:)
,index(after:)
以及index(_:offsetBy:)
對符合任何類型的方法Collection
的協議。這包括String
,以下圖所示,以及集合類型,如Array
,Dictionary
和Set
。
要將單個字符插入到指定索引處的字符串中,請使用該insert(_:at:)
方法,並在指定索引處插入另外一個字符串的內容,請使用該insert(contentsOf:at:)
方法。
要從指定索引處的字符串中刪除單個字符,請使用該remove(at:)
方法,並刪除指定範圍內的子字符串,請使用如下removeSubrange(_:)
方法:
注意
您可使用insert(_:at:)
,insert(contentsOf:at:)
,remove(at:)
,和removeSubrange(_:)
對符合任何類型的方法RangeReplaceableCollection
的協議。這包括String
,以下圖所示,以及集合類型,如Array
,Dictionary
和Set
。
從字符串中獲取子字符串時 - 例如,使用下標或相似方法prefix(_:)
- 結果是一個實例Substring
,而不是另外一個字符串。Swift中的子字符串與字符串具備大多數相同的方法,這意味着您能夠像處理字符串同樣使用子字符串。可是,與字符串不一樣,您在對字符串執行操做時僅使用子字符串很短的時間。當您準備好將結果存儲更長時間時,將子字符串轉換爲實例String
。例如:
與字符串同樣,每一個子字符串都有一個內存區域,用於存儲構成子字符串的字符。字符串和子字符串之間的區別在於,做爲性能優化,子字符串能夠重用用於存儲原始字符串的部份內存,或者用於存儲另外一個子字符串的內存的一部分。(字符串具備相似的優化,但若是兩個字符串共享內存,則它們是相等的。)此性能優化意味着在修改字符串或子字符串以前,您沒必要支付複製內存的性能成本。如上所述,子串不適合長期存儲 - 由於它們重用原始字符串的存儲,只要使用任何子字符串,整個原始字符串就必須保存在內存中。
在上面的示例中,greeting
是一個字符串,這意味着它有一個內存區域,其中存儲了構成字符串的字符。由於beginning
是子串greeting
,因此它重用了使用的內存greeting
。相反,newString
是一個字符串 - 當它從子字符串建立時,它有本身的存儲空間。下圖顯示了這些關係:
注意
兩者String
並Substring
符合StringProtocol
協議,這意味着它的常方便的字符串操做函數接受StringProtocol
的值。您可使用a String
或Substring
值調用此類函數。
Swift提供了三種比較文本值的方法:字符串和字符相等,前綴相等和後綴相等。
字符串和字符平等與「等於」運算符(檢查==
)和「不等於」運算符(!=
),如在比較操做符:
若是兩個String
值(或兩個Character
值)的擴展字形簇在規範上等效,則它們被認爲是相等的。若是擴展的字形集羣具備相同的語言含義和外觀,則它們在規範上是等效的,即便它們是由幕後的不一樣Unicode標量組成的。
例如,()在規範上等效於()後跟()。這兩個擴展的字形集合都是表示字符的有效方式,所以它們被認爲是規範等價的:LATIN SMALL LETTER E WITH ACUTE
U+00E9
LATIN SMALL LETTER E
U+0065
COMBINING ACUTE ACCENT
U+0301
é
相反,(或),如英語中所使用的,並不等同於俄語中使用的(,或)。角色在視覺上類似,但不具備相同的語言含義:LATIN CAPITAL LETTER A
U+0041
"A"
CYRILLIC CAPITAL LETTER A
U+0410
"А"
注意
Swift中的字符串和字符比較不是區域設置敏感的。
要檢查字符串是否具備特定字符串前綴或後綴,請調用字符串hasPrefix(_:)
和hasSuffix(_:)
方法,二者都採用類型的單個參數String
並返回布爾值。
下面的例子考慮了一組字符串,這些字符串表明了莎士比亞的「 羅密歐與朱麗葉 」前兩部劇中的場景位置:
您可使用數組中的hasPrefix(_:)
方法romeoAndJuliet
來計算播放的第1幕中的場景數量:
一樣,使用該hasSuffix(_:)
方法計算在Capulet的豪宅和Friar Lawrence的單元格內或周圍發生的場景數量:
注意
該hasPrefix(_:)
和hasSuffix(_:)
在每個串的方法執行所述擴展字形簇之間的字符逐字符規範等價比較,如在所述的字符串和字符平等。
將Unicode字符串寫入文本文件或其餘存儲時,該字符串中的Unicode標量將以多種Unicode定義的編碼形式之一進行編碼。每一個表單都以小塊(稱爲代碼單元)對字符串進行編碼。這些包括UTF-8編碼格式(將字符串編碼爲8位代碼單元),UTF-16編碼格式(將字符串編碼爲16位代碼單元)和UTF-32編碼格式(對其進行編碼)字符串爲32位代碼單元)。
Swift提供了幾種不一樣的方法來訪問字符串的Unicode表示。您可使用for
- in
語句迭代字符串,以Character
Unicode擴展字形集羣的形式訪問其各個值。使用字符中描述了此過程。
或者,訪問String
其餘三個符合Unicode的表示之一中的值:
utf8
屬性訪問)utf16
屬性訪問)unicodeScalars
屬性訪問)下面各實施例中示出了下面的字符串,它是由所述字符的向上的不一樣表示D
,o
,g
,‼
(或Unicode標),以及🐶字符(或Unicode標):DOUBLE EXCLAMATION MARK
U+203C
DOG FACE
U+1F436
您能夠String
經過迭代其utf8
屬性來訪問a的UTF-8表示。此屬性的類型String.UTF8View
是無符號8位(UInt8
)值的集合,對於字符串的UTF-8表示形式,每一個字節對應一個值:
在上面的例子中,前三個十進制codeUnit
值(68
,111
,103
)所表示的字符D
,o
和g
,其UTF-8表示相同的ASCII表示。接下來的三個十進制codeUnit
值(226
,128
,188
)是一個三字節UTF-8表示的字符。最後四個值(,,,)是一個四字節UTF-8表示的字符。DOUBLE EXCLAMATION MARK
codeUnit
240
159
144
182
DOG FACE
您能夠String
經過迭代其utf16
屬性來訪問a的UTF-16表示。此屬性的類型String.UTF16View
是無符號16位(UInt16
)值的集合,對於字符串的UTF-16表示形式,每一個16位代碼單元對應一個值:
再次,前三個codeUnit
值(68
,111
,103
)所表示的字符D
,o
和g
,其UTF-16代碼單元具備如在字符串的UTF-8表示相同的值(由於這些Unicode標量表示ASCII字符)。
第四codeUnit
值(8252
)是十六進制值的十進位等值203C
,它表明了Unicode標U+203C
爲字符。此字符能夠表示爲UTF-16中的單個代碼單元。DOUBLE EXCLAMATION MARK
第五和第六個codeUnit
值(55357
和56374
)是字符的UTF-16代理對錶示。這些值的高代理值(十進制值)和一個低代理值(十進制值)。DOG FACE
U+D83D
55357
U+DC36
56374
您能夠String
經過迭代其unicodeScalars
屬性來訪問值的Unicode標量表示。此屬性的類型是類型UnicodeScalarView
值的集合UnicodeScalar
。
每一個UnicodeScalar
都有一個value
屬性,返回標量的21位值,表示在一個UInt32
值內:
的value
前三個屬性UnicodeScalar
值(68
,111
,103
)再次表示字符D
,o
和g
。
第四codeUnit
值(8252
)再次是十六進制值的十進位等值203C
,它表明了Unicode標U+203C
爲字符。DOUBLE EXCLAMATION MARK
在value
第五和最後的屬性UnicodeScalar
,128054
是十六進制值的十進位等值1F436
,它表明了Unicode標U+1F436
爲字符。DOG FACE
做爲查詢其value
屬性的替代方法,每一個UnicodeScalar
值也可用於構造新String
值,例如使用字符串插值: