如何从HTML字符串解析JSON字段?求替代rangeOfString的有效方案
更可靠的HTML内嵌JSON解析方案
我懂你这种用rangeOfString折腾半天却拿不到想要结果的挫败感——手动截取字符串确实太脆弱了,HTML结构哪怕多个空格或者换行就会失效。咱们换个更靠谱的方案,分两步走:先精准提取<body>里的JSON字符串,再用系统的JSON解析工具转成对象,就能直接拿到type和message字段了。
步骤1:提取<body>内的JSON内容
用正则表达式匹配<body>和</body>之间的内容,这比rangeOfString灵活得多,能兼容HTML里的换行、空格等格式变化。
步骤2:解析JSON为字典/对象
拿到纯净的JSON字符串后,用系统自带的JSON解析API(Objective-C的NSJSONSerialization或Swift的JSONSerialization/JSONDecoder)转成可直接访问的对象,避免手动截取字段的各种坑。
Objective-C 实现示例
NSString *htmlResponse = @"<html><head></head><body>{\"data\":{\"type\":\"success\",\"message\":\"Thanks for order with XYZ.\"}}</body></html>"; // 正则匹配<body>标签内的所有内容 NSRegularExpression *bodyRegex = [NSRegularExpression regularExpressionWithPattern:@"<body>(.*?)</body>" options:NSRegularExpressionDotMatchesLineSeparators error:nil]; NSTextCheckingResult *matchResult = [bodyRegex firstMatchInString:htmlResponse options:0 range:NSMakeRange(0, htmlResponse.length)]; if (matchResult) { // 提取JSON字符串 NSString *jsonString = [htmlResponse substringWithRange:[matchResult rangeAtIndex:1]]; // 转成NSData并解析为字典 NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *parseError = nil; NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&parseError]; if (!parseError) { // 直接访问目标字段 NSDictionary *dataDict = responseDict[@"data"]; NSString *type = dataDict[@"type"]; NSString *message = dataDict[@"message"]; NSLog(@"Type: %@ | Message: %@", type, message); // 这里就可以用type和message做后续处理了 } else { NSLog(@"JSON解析失败:%@", parseError.localizedDescription); } } else { NSLog(@"未找到<body>标签内的内容"); }
Swift 实现示例
let htmlResponse = "<html><head></head><body>{\"data\":{\"type\":\"success\",\"message\":\"Thanks for order with XYZ.\"}}</body></html>" do { // 正则匹配<body>内的JSON内容 let regex = try NSRegularExpression(pattern: "<body>(.*?)</body>", options: .dotMatchesLineSeparators) guard let match = regex.firstMatch(in: htmlResponse, range: NSRange(htmlResponse.startIndex..., in: htmlResponse)), let jsonStringRange = Range(match.range(at: 1), in: htmlResponse) else { print("无法提取<body>内的JSON内容") return } let jsonString = String(htmlResponse[jsonStringRange]) // 解析JSON guard let jsonData = jsonString.data(using: .utf8), let responseDict = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any], let dataDict = responseDict["data"] as? [String: String] else { print("JSON解析失败") return } // 获取目标字段 let type = dataDict["type"] let message = dataDict["message"] print("Type: \(type ?? "") | Message: \(message ?? "")") } catch { print("错误:\(error.localizedDescription)") }
为什么这个方案更优?
- 健壮性强:正则匹配能忽略HTML的格式变化(比如换行、空格),不像
rangeOfString依赖固定的字符位置; - 可靠性高:用系统原生的JSON解析API,能处理所有合法的JSON格式,不会因为JSON内的特殊字符(比如引号、转义符)失效;
- 可扩展性好:如果后续JSON结构新增字段,不需要修改提取逻辑,直接访问新字段即可。
内容的提问来源于stack exchange,提问作者Joyal Clifford
相关产品推荐
相关产品推荐

