我们知道我们可以用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'某处 –