在 swift 中解析字符串

parsing String in swift

提问人:Navaneeth A S 提问时间:2/22/2023 最后编辑:udiNavaneeth A S 更新时间:2/22/2023 访问量:107

问:

解析以下字符串以读取名称和卷号的最佳方法

"Student"={"Info"={}},
"Student"={"SchoolName"="abc","place"="abc","Info"={"Name"="student1","class"="class1"}},
"Student"={"SchoolName"="abc","place"="bbc,"Info"={"Name"="student2","class"="class1"}}

是否可以将此字符串直接解析为字典数组?

快速 字符串 解析

评论

0赞 vadian 2/22/2023
如果后面有双引号,则可以通过替换某些字符来很容易地将其转换为 JSON。如果没有,那就很难做到。"bbc
0赞 Navaneeth A S 2/22/2023
是的,BBL 后面也有双引号

答:

2赞 udi 2/22/2023 #1

如果这是一个json,事情可能会容易得多。由于这是一个字符串,除了使用正则表达式模式之外,我看不到其他方法。

let string = """
"Student"={"Info":{}},
"Student"={"SchoolName":"abc","place":"abc","Info":{"Name":"student1","class":"class1"}},
"Student"={"SchoolName":"abc","place":"bbc","Info":{"Name":"student2","class":"class1"}}
"""

let pattern = #"Name":"([^"]+)","class":"([^"]+)""#

var array: [[String: String]] = []

let regex = try! NSRegularExpression(pattern: pattern, options: [])

regex.enumerateMatches(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { match, _, _ in
    if let match = match {
        
        let nameRange = Range(match.range(at: 1), in: string)!
        let classRange = Range(match.range(at: 2), in: string)!
        
        let name = String(string[nameRange])
        let classValue = String(string[classRange])
        
        array.append(["Name": name, "RollNumber": classValue])
    }
}
//output
print(array) //[["Name": "student1", "RollNumber": "class1"], ["Name": "student2", "RollNumber": "class1"]]

print(array[0]["Name"]) //Optional("student1")
print(array[0]["RollNumber"]) //Optional("class1")

仅供参考 :如果这是JSON的一部分,请将其解码为json。不要尝试解码为字符串。

2赞 vadian 2/22/2023 #2

如果保证所有键都用双引号括起来,则可以通过将字符替换为缺少的大括号和括号并添加这些字符,将字符串转换为有效的 JSON。=:

var string = """
"Student"={"Info"={}},
"Student"={"SchoolName"="abc","place"="abc","Info"={"Name"="student1","class"="class1"}},
"Student"={"SchoolName"="abc","place"="bbc","Info"={"Name"="student2","class"="class1"}}
"""

string = string.replacingOccurrences(of: "=", with: ":")
string = string.replacingOccurrences(of: "\"Student", with: "{\"Student")
string = "[" + string.replacingOccurrences(of: "},", with: "}},") + "}]"

匹配的结构是

struct Root : Decodable {
    private enum CodingKeys: String, CodingKey { case student = "Student"}
    
    let student: Student?
}

struct Student : Decodable {
    private enum CodingKeys: String, CodingKey { case schoolName = "SchoolName", place, info = "Info" }

    let schoolName: String?
    let place: String?
    let info: Info
}

struct Info : Decodable {
    private enum CodingKeys: String, CodingKey { case name = "Name", className = "class" }  

    let name: String?
    let className: String?
}

您可以解码和显示数据

do {
    let result = try JSONDecoder().decode([Root].self, from: Data(string.utf8))
    for item in result where item.student?.info.name != nil {
        let info = item.student!.info
        print("Name", info.name!, "Class", info.className ?? "No class available")
    }
} catch {
    print(error)
}