如何仅将可转换数据转为JSON?以window.digitalData为例
我来帮你搞定这两个JSON转换的问题,针对你给出的Swift代码场景,咱们一步步拆解解决:
1. 如何仅将可转换的数据转换为JSON格式?
核心思路是先从混合内容里剥离出合法的JSON片段,再对这些片段进行解析——毕竟JSONSerialization只能处理纯JSON格式的字符串,混杂其他代码肯定会失败。通用步骤如下:
- 识别字符串中符合JSON语法的结构(通常以
{/[开头,对应}/]结尾,要处理嵌套情况) - 逐个提取这些片段,尝试用
JSONSerialization解析 - 收集所有解析成功的JSON数据,跳过无效片段
2. 如何从指定字符串中提取并转换
window.digitalData的JSON数据? 针对你给出的包含JS代码的字符串,我们需要精准定位window.digitalData对应的JSON对象,再单独解析。这里要注意处理嵌套的花括号(避免被后续代码里的}提前截断),具体Swift代码实现如下:
let str = "window.digitalData = {\"version\":\"1.0\",\"page\":{\"title\":\"Home Page\"}}; if (typeof listing != 'undefined' && listing.items.length > 0) { /* 其他JS代码 */ }" // 第一步:精准提取window.digitalData对应的JSON字符串 func extractDigitalData(from string: String) -> String? { // 定位到"window.digitalData = "的位置 guard let prefixRange = string.range(of: "window.digitalData = ") else { return nil } let startSearchIndex = prefixRange.upperBound // 找到JSON对象的起始{ guard let openBraceIndex = string[startSearchIndex...].firstIndex(of: "{") else { return nil } // 匹配对应的闭合}(处理嵌套花括号) var braceCount = 1 var currentIndex = string.index(after: openBraceIndex) let endOfString = string.endIndex while currentIndex < endOfString && braceCount > 0 { let char = string[currentIndex] if char == "{" { braceCount += 1 } else if char == "}" { braceCount -= 1 } currentIndex = string.index(after: currentIndex) } // 确认找到完整的闭合括号 guard braceCount == 0 else { return nil } // 提取纯JSON字符串 let jsonRange = openBraceIndex..<string.index(before: currentIndex) return String(string[jsonRange]) } // 第二步:解析提取到的JSON if let digitalDataJsonStr = extractDigitalData(from: str), let jsonData = digitalDataJsonStr.data(using: .utf8), let parsedJSON = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] { print("解析成功的window.digitalData:", parsedJSON) } else { print("无法提取或解析有效的JSON数据") }
代码说明:
- 先通过字符串匹配定位到
window.digitalData =的位置,确保只处理目标数据 - 通过计数花括号的方式,精准匹配嵌套结构的闭合括号,避免被后续JS代码干扰
- 提取出纯JSON字符串后,再用你原来的
JSONSerialization流程解析,就不会报错了
如果需要处理更通用的场景(比如字符串里有多个JSON片段),可以用下面的通用函数提取所有可转换的JSON:
func extractAllValidJSON(from string: String) -> [[String: Any]] { var validJSONs = [[String: Any]]() var currentIndex = string.startIndex let endIndex = string.endIndex while currentIndex < endIndex { // 寻找下一个JSON结构的起始符号({或[) guard let startCharIndex = string[currentIndex...].firstIndex(where: { $0 == "{" || $0 == "[" }) else { break } let startChar = string[startCharIndex] let endChar: Character = startChar == "{" ? "}" : "]" // 匹配对应的闭合符号,处理嵌套 var bracketCount = 1 var tempIndex = string.index(after: startCharIndex) while tempIndex < endIndex && bracketCount > 0 { let char = string[tempIndex] if char == startChar { bracketCount += 1 } else if char == endChar { bracketCount -= 1 } tempIndex = string.index(after: tempIndex) } // 如果找到完整的JSON结构,尝试解析 if bracketCount == 0 { let jsonRange = startCharIndex..<string.index(before: tempIndex) let jsonStr = String(string[jsonRange]) if let data = jsonStr.data(using: .utf8), let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] { validJSONs.append(json) } currentIndex = tempIndex } else { currentIndex = string.index(after: startCharIndex) } } return validJSONs } // 使用示例 let mixedContent = "随机文本 {\"name\":\"Alice\",\"age\":30} 更多内容 [1,2,3] 其他 {\"key\":\"value\"}" let allValidJSON = extractAllValidJSON(from: mixedContent) print("所有可转换的JSON数据:", allValidJSON)
内容的提问来源于stack exchange,提问作者Abdymazhit
相关产品推荐
相关产品推荐

