Swift UTF16子串

时间:2015-12-07 19:41:17

标签: string swift encoding

我以下列格式从服务器收到一个字符串:

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中完成(或者如果可以的话)。

2 个答案:

答案 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

编辑:谢谢,Martin R,你提供的链接确实在纯粹的Swift中工作:D

编辑:

utf16的{​​{1}}属性的String属性是UTF16的长度。这是一个简单的解析器,用于您的目的,效率不高,但它完成了工作:

count

我实际上试图让它更有效率,但是Swift的String机制推动了它。我挑战任何人为此创建一个漂亮的高效防撞解决方案..