我們知道我們可以用UTF8代碼單元打印每個字符嗎? 然後,如果我們有這些字符的代碼單元,我們如何創建一個字符串與他們?如何在Swift中從UTF8創建一個字符串?
回答
這是一個可能的解決方案(現在更新的夫特2):
let utf8 : [CChar] = [65, 66, 67, 0]
if let str = utf8.withUnsafeBufferPointer({ String.fromCString($0.baseAddress) }) {
print(str) // Output: ABC
} else {
print("Not a valid UTF-8 string")
}
內閉合,$0
是UnsafeBufferPointer<CChar>
指向陣列的連續的存儲。由此可以創建Swift String
。
或者,如果你喜歡的輸入作爲無符號字節:
let utf8 : [UInt8] = [0xE2, 0x82, 0xAC, 0]
if let str = utf8.withUnsafeBufferPointer({ String.fromCString(UnsafePointer($0.baseAddress)) }) {
print(str) // Output: €
} else {
print("Not a valid UTF-8 string")
}
我會做這樣的事情,也可能是沒有這樣優雅比「指針」工作,但它的工作好,這些是相當多的關於一堆新+=
運營商String
,如:
@infix func += (inout lhs: String, rhs: (unit1: UInt8)) {
lhs += Character(UnicodeScalar(UInt32(rhs.unit1)))
}
@infix func += (inout lhs: String, rhs: (unit1: UInt8, unit2: UInt8)) {
lhs += Character(UnicodeScalar(UInt32(rhs.unit1) << 8 | UInt32(rhs.unit2)))
}
@infix func += (inout lhs: String, rhs: (unit1: UInt8, unit2: UInt8, unit3: UInt8, unit4: UInt8)) {
lhs += Character(UnicodeScalar(UInt32(rhs.unit1) << 24 | UInt32(rhs.unit2) << 16 | UInt32(rhs.unit3) << 8 | UInt32(rhs.unit4)))
}
注:您可以擴展與overridin支持的運營商名單g+
運營商以及定義完全可交換運營商的列表String
。
,現在你可以到String
追加使用Unicode(UTF-8,UTF-16和UTF-32)字符例如像:
var string: String = "signs of the Zodiac: "
string += (0x0, 0x0, 0x26, 0x4b)
string += (38)
string += (0x26, 76)
只是一句話:你的代碼創建從UTF-32輸入一個字符串(如果我理解正確的話)和雷來自UTF-8輸入。再次讀這個問題我不是100%確定這裏要求什麼。 OP提到兩個「UTF-8」和「碼點」 ... –
@MartinR,你是對的,是公平的,我不知道真正的問題提出,其原因是,就像你剛纔說的一樣。 .. – holex
請注意,Unicode代碼點的UTF-8序列具有1個,2個,3個或4個字節。 –
改善馬丁的r答案
import AppKit
let utf8 : CChar[] = [65, 66, 67, 0]
let str = NSString(bytes: utf8, length: utf8.count, encoding: NSUTF8StringEncoding)
println(str) // Output: ABC
import AppKit
let utf8 : UInt8[] = [0xE2, 0x82, 0xAC, 0]
let str = NSString(bytes: utf8, length: utf8.count, encoding: NSUTF8StringEncoding)
println(str) // Output: €
發生了什麼事是Array
可以自動轉換到CConstVoidPointer
可用於與NSSString(bytes: CConstVoidPointer, length len: Int, encoding: Uint)
請注意,您的代碼也會將0字節轉換爲創建的NSString中的NUL字符。 –
這是可能的UTF8編碼點轉換爲字符串雨燕習慣用法使用UTF8
雨燕類中創建的字符串。雖然從String轉換爲UTF8更容易!
import Foundation
public class UTF8Encoding {
public static func encode(bytes: Array<UInt8>) -> String {
var encodedString = ""
var decoder = UTF8()
var generator = bytes.generate()
var finished: Bool = false
do {
let decodingResult = decoder.decode(&generator)
switch decodingResult {
case .Result(let char):
encodedString.append(char)
case .EmptyInput:
finished = true
/* ignore errors and unexpected values */
case .Error:
finished = true
default:
finished = true
}
} while (!finished)
return encodedString
}
public static func decode(str: String) -> Array<UInt8> {
var decodedBytes = Array<UInt8>()
for b in str.utf8 {
decodedBytes.append(b)
}
return decodedBytes
}
}
func testUTF8Encoding() {
let testString = "A UTF8 String With Special Characters: "
let decodedArray = UTF8Encoding.decode(testString)
let encodedString = UTF8Encoding.encode(decodedArray)
XCTAssert(encodedString == testString, "UTF8Encoding is lossless: \(encodedString) != \(testString)")
}
另一替代方案建議:
使用
NSString
調用Objective-C的橋;使用
UnicodeScalar
容易出錯,因爲它將UnicodeScalars直接轉換爲字符,忽略複雜的字素集羣;和使用
String.fromCString
可能是不安全的,因爲它使用指針。
我一直在尋找一個全面的答案在Swift我自己的字符串操作。依靠鑄造NSString
和其他不安全的指針魔術就是不適合我。這裏是一個安全的選擇:
首先,我們要擴展UInt8
。這是CodeUnit
後面的原始類型。
extension UInt8 {
var character: Character {
return Character(UnicodeScalar(self))
}
}
這將使我們能夠做這樣的事情:
let codeUnits: [UInt8] = [
72, 69, 76, 76, 79
]
let characters = codeUnits.map { $0.character }
let string = String(characters)
// string prints "HELLO"
配備了這個擴展,我們現在正在修改字符串。
let string = "ABCDEFGHIJKLMONP"
var modifiedCharacters = [Character]()
for (index, utf8unit) in string.utf8.enumerate() {
// Insert a "-" every 4 characters
if index > 0 && index % 4 == 0 {
let separator: UInt8 = 45 // "-" in ASCII
modifiedCharacters.append(separator.character)
}
modifiedCharacters.append(utf8unit.character)
}
let modifiedString = String(modifiedCharacters)
// modified string == "ABCD-EFGH-IJKL-MONP"
有雨燕3.0的版本Martin R答案
public class UTF8Encoding {
public static func encode(bytes: Array<UInt8>) -> String {
var encodedString = ""
var decoder = UTF8()
var generator = bytes.makeIterator()
var finished: Bool = false
repeat {
let decodingResult = decoder.decode(&generator)
switch decodingResult {
case .scalarValue(let char):
encodedString += "\(char)"
case .emptyInput:
finished = true
case .error:
finished = true
}
} while (!finished)
return encodedString
}
public static func decode(str: String) -> Array<UInt8> {
var decodedBytes = Array<UInt8>()
for b in str.utf8 {
decodedBytes.append(b)
}
return decodedBytes
}
}
如果你想顯示從UTF-8字符串的表情符號,只是用戶convertEmojiCodesToString低於方法。這是正常的像「U + 1F52B」(表情符)的字符串或「U + 1F1E6 U + 1F1F1」(國國旗的表情符號)
class EmojiConverter {
static func convertEmojiCodesToString(_ emojiCodesString: String) -> String {
let emojies = emojiCodesString.components(separatedBy: " ")
var resultString = ""
for emoji in emojies {
var formattedCode = emoji
formattedCode.slice(from: 2, to: emoji.length)
formattedCode = formattedCode.lowercased()
if let charCode = UInt32(formattedCode, radix: 16),
let unicode = UnicodeScalar(charCode) {
let str = String(unicode)
resultString += "\(str)"
}
}
return resultString
}
}
斯威夫特3
let s = String(bytes: arr, encoding: .utf8)
如果您從原始緩衝區開始,例如從文件句柄返回的數據對象(在本例中,取自管道對象):
let data = pipe.fileHandleForReading.readDataToEndOfFile()
var unsafePointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
data.copyBytes(to: unsafePointer, count: data.count)
let output = String(cString: unsafePointer)
- 1. 如何在Swift中創建一個Javascript安全字符串?
- 2. 如何創建一個非UTF8字符串?
- 3. 如何在python中創建一個字符串字符串
- 4. 從另一個字符串中創建一個字符串?
- 5. 如何在swift中從base64字符串創建GIF
- 6. 如何在Google V8引擎中創建utf8字符串
- 7. 在Swift中創建字符串模板?
- 8. 無法從字符串創建類Swift
- 9. 如何從三個變量中創建一個字符串?
- 10. 創建一個無效的UTF8 perl字符串?
- 11. 試圖從字符串數組中創建一個字符串
- 12. 如何創建一個空字符串?
- 13. 從字符串中創建一個數組,然後在字符串中逐個創建一個
- 14. 如何從字符串數組中創建一個字符串C
- 15. 如何從一個字符串創建一個UserControl
- 16. 在python中創建一個字符串
- 17. 如何從字符串中創建XElement?
- 18. 從字符串創建一個MySQL SET
- 19. 創建一個從字符串
- 20. 創建一個從字符串
- 21. 從NSArray創建一個json字符串
- 22. 創建一個從字符串
- 23. 從字符串創建一個Jar?
- 24. 創建一個從字符串
- 25. 從字符串創建一個視圖
- 26. PHP - 創建一個從字符串
- 27. 從字符串創建一個數組
- 28. 創建一個從字符串
- 29. 如何從Java中的字符串創建一個XML對象?
- 30. 如何從C宏的值中創建一個字符串?
使用Swift語法編寫的C代碼......並且比C更醜陋(這可能是一件好事,所以人們希望避免它們) –
@BryanChen:我剛纔試圖提出一個不使用Swift的解決方案基金會和Objective-C類... –
我認爲真正的雨燕方法必須使用'Character'和'UTF8'某處 –