You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅将可转换数据转为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数据")
}

代码说明:

  1. 先通过字符串匹配定位到window.digitalData = 的位置,确保只处理目标数据
  2. 通过计数花括号的方式,精准匹配嵌套结构的闭合括号,避免被后续JS代码干扰
  3. 提取出纯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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:32:43