我以下列格式从服务器收到一个字符串:
118|...message...215|...message2...
基本上,消息 length 后跟一个管道和消息本身,重复多个消息。邮件编码为UTF16。
我正在寻找一种在Swift中解析它的方法。我知道我可以将其转换为NSString
并使用标准索引/范围,因为UTF16是NSString使用的,但我想知道 Swift 处理这个问题的方法是什么?我似乎找不到基于UTF16编码从String
中拉出子串的方法。
我不是试图用原始UTF16数据初始化 String
(有很多方法可以做到这一点)。我已经有了字符串,所以我试图以上述格式取一个String
并解析它。我遇到的问题是服务器给我的消息长度是基于UTF16。我不能简单地提取长度并在索引上调用String.advance(messageLength)
,因为我给出的长度与Swift前进的字形簇不匹配。我的问题是我无法从字符串中提取Swift中的消息。我必须将其转换为NSString
,然后在其上使用“普通”NSRange
。我的问题是如何通过为第一个管道提取基于 search 的范围来拉出子串,然后使用UTF16中解析器提供的长度。
使用NSString
这一切都非常简单。不确定如何在纯Swift中完成(或者如果可以的话)。
答案 0 :(得分:3)
这是我解析字符串中的消息。我不得不改变你的长度来处理字符串。
let message = "13|...message...14|...message2..."
let utf16 = message.utf16
var startingIndex = message.utf16.startIndex
var travellingIndex = message.utf16.startIndex
var messages = [String]()
var messageLength: Int
while travellingIndex != message.utf16.endIndex {
// Start walking through each character
if let char = String(utf16[travellingIndex..<travellingIndex.successor()]) {
// When we find the pipe symbol try to parse out the message length
if char == "|" {
if let stringNumber = Int(String(utf16[startingIndex..<travellingIndex])) {
messageLength = stringNumber
// We found the lenght, now skip the pipe character
startingIndex = travellingIndex.successor()
// move the travelingIndex to the end of the message
travellingIndex = travellingIndex.advancedBy(messageLength)
// get the message and put it into an array
if let message = String(utf16[startingIndex...travellingIndex]) {
messages.append(message)
startingIndex = travellingIndex.successor()
}
}
}
}
travellingIndex = travellingIndex.successor()
}
print(messages)
我最后得到的输出是:
["...message...", "...message2..."]
答案 1 :(得分:0)
Foundation
框架将String
扩展为可从数据初始化:
import Foundation
let string = String(data: data, encoding: NSUTF16StringEncoding)
除非您自己实施解码,否则无法摆脱Foundation
。请注意,随着Swift开源,Foundation
正在重新实现而没有Objective-C依赖here。
编辑:
utf16
的{{1}}属性的String
属性是UTF16的长度。这是一个简单的解析器,用于您的目的,效率不高,但它完成了工作:
count
我实际上试图让它更有效率,但是Swift的String机制推动了它。我挑战任何人为此创建一个漂亮的高效防撞解决方案..