Ios 分裂快弦复合体

Ios 分裂快弦复合体,ios,swift,Ios,Swift,我想拆分一个纯字符串的响应。答复如下: Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead 需要根据此响应创建字典,如,ResultSetDic[String:String] Status: N/A Host: somesite.com is Connection live: true Status Connectio

我想拆分一个纯字符串的响应。答复如下:

Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead
需要根据此响应创建字典,如,
ResultSetDic[String:String]

Status: N/A  
Host: somesite.com  
is Connection live: true  
Status Connection: deny  
heart beat: dead  
尝试使用各种方法(如NSRegularExpression、Range、Split)拆分响应字符串,但没有一种方法更干净,并且使用多个字符串结果集逐个解析,这是不整洁的

在字典中拆分响应的任何有用方法。
在上面的响应中,键始终是固定的。

使此可解析的是,每个
只是一个
单词
,并且
键和
之间用
分隔

首先,我识别下一个键的结尾,然后添加下一个单词作为其值

func testing() {
    let input = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

    var  step1 = input.split(separator: " ")
    guard let index = step1.firstIndex(where: { $0.contains(",") }) else {
        fatalError("Does not contain `,`. at the beginning.")
    }
    step1.removeFirst(index + 1)

    var step2 = step1
    var output = [String: String]()
    repeat {
        guard let index = step2.firstIndex(where: { $0.contains(":") }) else {
            // If the last part has no :, can add it under `end`.
            // output["end"] = step2.joined(separator: " ")
            step2.removeAll()
            break
        }
        let key = step2[0...index].joined(separator: " ").trimmingCharacters(in: CharacterSet(charactersIn: ":"))
        let value = step2[index + 1]
        output [key] = String(value)
        step2.removeFirst(index + 2)

    } while step2.count != 0

    output.forEach{
        print("\($0.key): \($0.value)")
    }
}


// Output:
// Host: somesite.com
// Status Connection: deny
// Status: N/A
// heart beat: dead
// is Connection live: true
编辑:
Array.firstIndex(其中:)
似乎是Xcode10+,因此在Xcode9.4中您可以尝试:

extension Array {
    func firstIndex(where predicate: (Element) throws -> Bool) rethrows -> Int? {
        for index in indices where try predicate(self[index]) { return index }
        return nil
    }
}
Edit2:一种向后兼容的方式,用于从Leo添加
.firstIndex(其中:)

extension Collection {
    func firstIndex(where predicate: (Element) throws -> Bool) rethrows -> Index? {
        return try index(where: predicate)
    }
}

使这个可解析的东西是,每个
只是一个
单词
,而
之间用
分隔

首先,我识别下一个键的结尾,然后添加下一个单词作为其值

func testing() {
    let input = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

    var  step1 = input.split(separator: " ")
    guard let index = step1.firstIndex(where: { $0.contains(",") }) else {
        fatalError("Does not contain `,`. at the beginning.")
    }
    step1.removeFirst(index + 1)

    var step2 = step1
    var output = [String: String]()
    repeat {
        guard let index = step2.firstIndex(where: { $0.contains(":") }) else {
            // If the last part has no :, can add it under `end`.
            // output["end"] = step2.joined(separator: " ")
            step2.removeAll()
            break
        }
        let key = step2[0...index].joined(separator: " ").trimmingCharacters(in: CharacterSet(charactersIn: ":"))
        let value = step2[index + 1]
        output [key] = String(value)
        step2.removeFirst(index + 2)

    } while step2.count != 0

    output.forEach{
        print("\($0.key): \($0.value)")
    }
}


// Output:
// Host: somesite.com
// Status Connection: deny
// Status: N/A
// heart beat: dead
// is Connection live: true
编辑:
Array.firstIndex(其中:)
似乎是Xcode10+,因此在Xcode9.4中您可以尝试:

extension Array {
    func firstIndex(where predicate: (Element) throws -> Bool) rethrows -> Int? {
        for index in indices where try predicate(self[index]) { return index }
        return nil
    }
}
Edit2:一种向后兼容的方式,用于从Leo添加
.firstIndex(其中:)

extension Collection {
    func firstIndex(where predicate: (Element) throws -> Bool) rethrows -> Index? {
        return try index(where: predicate)
    }
}

因为您有固定的键和响应格式,所以最好使用键的特定解析逻辑

let response = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

enum ResponseParseId: String {
    case status = "Status:"
    case host = "Host:"
    case isConnectionLive = "is Connection live:"
    case statusConnection = "Status Connection:"
    case heartBeat = "heart beat:"

    var key: String {
        switch self {
        case .status:
            return "Status"
        case .host:
            return "Host"
        case .isConnectionLive:
            return "is Connection live"
        case .statusConnection:
            return "Status Connection"
        case .heartBeat:
            return "heart beat"
        }
    }

    static var allIds: [ResponseParseId] = [.status, .host, .isConnectionLive, .statusConnection, .heartBeat]
}

func getValue(from response: String, for key: ResponseParseId) -> String? {
    let components = response.components(separatedBy: key.rawValue)
    if let substring = components.last?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) {
        let subcomponents = substring.components(separatedBy: " ")
        if let value = subcomponents.first {
            return value
    }
}
return nil
}

func getResponseDictionary(response: String) -> [String: String] {
    var dictionary: [String: String] = [:]
    for id in ResponseParseId.allIds {
        if let value = getValue(from: response, for: id) {
            dictionary[id.key] = value
        }
    }
        return dictionary
    }

let dictionary = getResponseDictionary(response: response)

print(dictionary)

因为您有固定的键和响应格式,所以最好使用键的特定解析逻辑

let response = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

enum ResponseParseId: String {
    case status = "Status:"
    case host = "Host:"
    case isConnectionLive = "is Connection live:"
    case statusConnection = "Status Connection:"
    case heartBeat = "heart beat:"

    var key: String {
        switch self {
        case .status:
            return "Status"
        case .host:
            return "Host"
        case .isConnectionLive:
            return "is Connection live"
        case .statusConnection:
            return "Status Connection"
        case .heartBeat:
            return "heart beat"
        }
    }

    static var allIds: [ResponseParseId] = [.status, .host, .isConnectionLive, .statusConnection, .heartBeat]
}

func getValue(from response: String, for key: ResponseParseId) -> String? {
    let components = response.components(separatedBy: key.rawValue)
    if let substring = components.last?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) {
        let subcomponents = substring.components(separatedBy: " ")
        if let value = subcomponents.first {
            return value
    }
}
return nil
}

func getResponseDictionary(response: String) -> [String: String] {
    var dictionary: [String: String] = [:]
    for id in ResponseParseId.allIds {
        if let value = getValue(from: response, for: id) {
            dictionary[id.key] = value
        }
    }
        return dictionary
    }

let dictionary = getResponseDictionary(response: response)

print(dictionary)

由于您正在解析的格式是固定的,并且具有已知的键,并且每次都是相同的格式,因此对于正则表达式来说,这是一个现成的问题:

let input = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

extension String {
    subscript(range:NSRange) -> Substring {
        let start = index(startIndex, offsetBy: range.location)
        let end = index(start, offsetBy: range.length)

        return self[start..<end]
    }
}

func parse(response:String) -> [String:String]? {
    guard let regex = try? NSRegularExpression(pattern: "Result Set, Status: (.*) Host: (.*) is Connection live: (.*) Status Connection: (.*) heart beat: (.*)", options:[]) else {
        return nil
    }

    guard let match = regex.firstMatch(in: input, range:NSRange(input.startIndex..<input.endIndex, in: input)) else {
        return nil
    }

    // Note that a much better approach here would be to *not* return
    //  a dictionary, but instead to return a struct containing all
    //  of the relevant data
    return [
        "Status": String(input[match.range(at: 1)]),
        "Host": String(input[match.range(at:2)]),
        "is Connection live": String(input[match.range(at:3)]),
        "Status Connection": String(input[match.range(at: 4)]),
        "heart beat": String(input[match.range(at:5)])
    ]
}
let input=“结果集,状态:N/A主机:somesite.com连接处于活动状态:真实状态连接:拒绝心跳:死亡”
扩展字符串{
下标(范围:NSRange)->子字符串{
让开始=索引(startIndex,offsetBy:range.location)
让结束=索引(开始,偏移:range.length)
返回self[start..[String:String]{
guard let regex=try?NSRegularExpression(模式:“结果集,状态:(*)主机:(*)连接处于活动状态:(*)状态连接:(*)心跳:(*),选项:[])其他{
归零
}

guard let match=regex.firstMatch(in:input,range:NSRange(input.startIndex..由于您有一个正在解析的固定格式,具有已知的键,并且每次都是相同的格式,这对于正则表达式来说是一个现成的问题:

let input = "Result Set, Status: N/A Host: somesite.com is Connection live: true Status Connection: deny heart beat: dead"

extension String {
    subscript(range:NSRange) -> Substring {
        let start = index(startIndex, offsetBy: range.location)
        let end = index(start, offsetBy: range.length)

        return self[start..<end]
    }
}

func parse(response:String) -> [String:String]? {
    guard let regex = try? NSRegularExpression(pattern: "Result Set, Status: (.*) Host: (.*) is Connection live: (.*) Status Connection: (.*) heart beat: (.*)", options:[]) else {
        return nil
    }

    guard let match = regex.firstMatch(in: input, range:NSRange(input.startIndex..<input.endIndex, in: input)) else {
        return nil
    }

    // Note that a much better approach here would be to *not* return
    //  a dictionary, but instead to return a struct containing all
    //  of the relevant data
    return [
        "Status": String(input[match.range(at: 1)]),
        "Host": String(input[match.range(at:2)]),
        "is Connection live": String(input[match.range(at:3)]),
        "Status Connection": String(input[match.range(at: 4)]),
        "heart beat": String(input[match.range(at:5)])
    ]
}
let input=“结果集,状态:N/A主机:somesite.com连接处于活动状态:真实状态连接:拒绝心跳:死亡”
扩展字符串{
下标(范围:NSRange)->子字符串{
让开始=索引(startIndex,offsetBy:range.location)
让结束=索引(开始,偏移:range.length)
返回self[start..[String:String]{
guard let regex=try?NSRegularExpression(模式:“结果集,状态:(*)主机:(*)连接处于活动状态:(*)状态连接:(*)心跳:(*),选项:[])其他{
归零
}

guard let match=regex.firstMatch(in:input,range:NSRange(input.startIndex..您从哪里获取此数据?他们是否有任何可用的机器可解析API?(JSON、XML、YAML等?)不,此数据由服务器发送,但采用字符串格式。(我希望不是JSON)您从何处获取此数据?他们是否有任何可用的机器可解析API?(JSON、XML、YAML等)?不,此数据是由服务器发送的,但采用字符串格式。(不是JSON,我希望是这样)感谢您的帮助。我无法看到step1.firstIndex。在Playerly字符串操作中获取错误。Playerly:161:27:错误:类型的值'[String.SubSequence]'(又称“Array”)没有成员“firstIndex”保护让index=step1.firstIndex(其中:{$0.contains(“:”)否则{更改它
index(of:)
index(其中:)
@iamMobile该函数似乎是在Xcode10/Swift4.2中添加的,请尝试上面的扩展以获得替代。或者尝试Leo的技巧。我在数组文档中找不到它们,但它们可能已从中删除了不推荐使用的/重命名的函数。@最好使用数组索引属性对其进行迭代。
对于索引中的索引,请尝试predicate(self[index]){return index}
@LeoDabus Damn这使事情变得简短,非常好!感谢您的帮助。我无法看到step1.firstIndex。在操场字符串操作中获取错误。操场:161:27:错误:类型为“[string.SubSequence]”的值(也称为“Array”)没有成员'firstIndex'保护让index=step1.firstIndex(其中:{$0.contains(“:”)否则{更改它
index(of:)
index(其中:)
@iamMobile该函数似乎是在Xcode10/Swift4.2中添加的,请尝试上面的扩展以获得替代。或者尝试Leo的技巧。我在数组文档中找不到它们,但它们可能已从中删除了不推荐使用的/重命名的函数。@最好使用数组索引属性对其进行迭代。
对于索引中的索引,请尝试predicate(self[index]){return index}
@LeoDabus Damn这使事情变得简短,非常好!有趣的方法!因为未知键无论如何都不能使用,所以定义它们是有意义的,使事情更坚固,更易于使用
->[ResponseParseID:String]
。有趣的方法!因为未知键无论如何都不能使用,所以定义它们是有意义的,这使得使用
->[ResponseParseID:String]
时更坚固、更容易使用。