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]
时更坚固、更容易使用。