2016-01-22 166 views
-2

如何獲取UTF-8編碼形式的字符串長度(不是字節數)(PHP的mb_strlen(.., 'UTF-8')等效項)?獲取UTF8中字符串的長度

我試過string.characters.count,但它不會像表情符號那樣爲特定字符返回正確的長度。

實施例:

let s = "✌️" 
print(s.characters.count) // prints 2, but should print 3. 
+2

您能否給一些輸入/輸出組合,如「ABC」 - > 3,「someUtf-8String」 - > 123對驗證我們的解決方案!? – luk2302

+0

您可以使用string.utf8.count獲得UTF-8計數。您可以使用Array(string.utf8)來獲取UTF-8代碼單元陣列。 –

+0

@ luk2302增加了一個例子。 – Code

回答

6

可以與.utf8屬性訪問字符串的UTF-8編碼。使用上count得到字符串中的UTF-8編碼單元的數量:

let string = "\u{1f603}" // One of the smiley face emojis... 

print(string.utf8.count) // prints "4" 

根據您編輯的問題,什麼你可能尋找的是用來串編碼UnicodeScalar S上的號碼。您訪問與unicodeScalars屬性:

let s = "✌️" 
print(s.unicodeScalars.count) // prints 3 

大家的原因是混淆是因爲你原來的問題要求在其UTF-8編碼格式的字符串的長度。您實際需要的答案與UTF-8編碼形式的字符串長度無關。

我認爲你對Unicode「擴展字形羣集」,Unicode代碼點和可用於編碼Unicode代碼點的各種編碼(如UTF-8)之間的區別感到困惑。

Swift中的Character表示Unicode稱之爲「擴展字形羣集」。也就是說,即使它是由多個Unicode代碼點組成,它也是一個單一的可視化字符。

Unicode代碼點是一個給定32位值的單個語言符號。兩個或多個Unicode代碼點可以組合在一起創建一個Character。在Swift中,Unicode代碼點由UnicodeScalar類型表示。

當需要存儲一個字符串,或通過互聯網發送它,或者將其轉換爲以字節表示的數據時,您必須決定如何對其進行編碼。有各種編碼,最常見的可能是UTF-8,它將字符串編碼爲一系列UInt8值。

這只是三個概念之間差異的簡短片段。這實際上是一個非常有趣的主題,如果你谷歌的一些條款,你會發現更多的好消息。

+0

我認爲你誤解了我的問題。我用一個例子編輯過。 – Code

+1

您問過如何獲取UTF-8編碼形式的字符串長度。這與用於對其進行編碼的字節數相同。如果這不是你所問的,那麼請編輯你的問題。 –

+0

我編輯了我的答案。 –

3
let str = "ačŘ" 
print("str has \(str.characters.count) characters") // 3 
print("and \(str.utf8.count) bytes as encoded in UTF-8") // 5 

更新(根據您的筆記)的字符

s.characters.forEach { (c) ->() in 
    let str = String(c) 
    print(str.utf8.map{$0}, "which represents character: ", c) 
    str.unicodeScalars.forEach({ (u) ->() in 
     print("composed from unicode scalar(s): ", u.debugDescription) 
    }) 
} 
/* 
[226, 156, 140] which represents character: ✌ 
composed from unicode scalar(s): "\u{270C}" 
[240, 159, 143, 191, 239, 184, 143] which represents character: ️ 
composed from unicode scalar(s): "\u{0001F3FF}" 
composed from unicode scalar(s): "\u{FE0F}" 
*/ 

Unicode中的每個字符可以由一個或多個Unicode標量來表示

let s = "✌️" 

let arr:[UInt8] = [226, 156, 140, 240, 159, 143, 191, 239, 184, 143] 
var arrCchar = arr.map { (uint8) -> Int8 in 
    Int8(bitPattern: uint8) 
} 
arrCchar += [0] // to be null terminated 

let str = String.fromCString(&arrCchar) 
print(str) // Optional("✌️") 
s == str // TRUE !!!! 

。 unicode標量是一個字符或修飾符的唯一21位數字(和名稱),例如LOWERCASE LATIN LETTER A(「a」)的U + 0061或FRONT-FACING BABY CHICK的U + 1F425(「\ U0001f425 「)。 將Unicode字符串寫入文本文件或其他存儲器時,這些unicode標量將以Unicode定義的幾種格式之一進行編碼。每種格式都將字符串編碼爲稱爲代碼單元的小塊。這些格式包括UTF-8格式(將字符串編碼爲8位代碼單元)和UTF-16格式(將字符串編碼爲16位代碼單元)。

//從蘋果開發者迅速編程指南複製

+0

我認爲你誤解了我的問題。我用一個例子編輯過。 – Code

+0

let s =「✌️」; print(s.characters.count)// 2 ???至少在我的電腦上。試試s.characters.forEach {print($ 0)}。順便說一下你的s有10個字節,如果編碼爲UTF-8 – user3441734

+0

我不明白你在說什麼。我知道它是10個字節。 '.characters.count'打印2,但我想要的值是3. – Code