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

使用原生JavaScript解析嵌套字符串对象的问题求助

如何解析嵌套的非标准JSON字符串为JavaScript对象?

我尝试解析一个嵌套字符串对象以返回对应的Object类型数据。例如,给定字符串:'{dog : cat, joe: { jane: cat, peanut : dog }, fat : skinny}',希望将其转换为Object类型,返回值为:{dog : cat, joe: { jane: cat, peanut : dog }, fat : skinny}。

我先看了你写的代码:

function Parse(string) {
 if (string[0] == '{' && string[string.length - 1] == '}') {
  const inObj = string.substring(1, string.length - 1);
  const arr = inObj.split(',');
  const keyVal = arr.map(c => c.split(':'));
  const obj = {};
  for (var i = 0; i < keyVal.length; i++) {
   let ele = keyVal[i];
   if (ele[1].startsWith('{')) {
    let string2 = ele[1];
    for (var j = i + 1; i < keyVal.length; i++) {
     console.log(keyVal[j]);
     if (keyVal[j].endsWith('}')) {
      string2 += keyVal[j];
      break;
     } else {
      string2 += keyVal[j];
     }
    }
    obj[ele[0]] = JSONParser(string2);
   } else {
    obj[ele[0]] = ele[1];
   }
  }
  return obj;
 }
}

你的思路方向是对的,但有几个关键问题导致代码无法正常工作:

  • 直接按逗号分割会破坏嵌套结构:嵌套对象里的逗号会被当成外层键值对的分隔符,导致拆分后的数组元素完全错误。
  • 内层循环的索引逻辑混乱:你在内层循环里修改了外层的i变量,会直接跳过很多外层元素,遍历逻辑彻底出错。
  • 忽略了空格处理:原字符串里的空格(比如dog : cat)会留在键和值里,导致结果不符合预期。
  • 函数名不一致:你调用了JSONParser但定义的函数是Parse,会直接抛出引用错误。

正确的解析思路

解析这类嵌套结构,不能简单用固定字符分割,必须通过追踪括号层级来区分外层和内层的分隔符。具体步骤如下:

  1. 先清理字符串首尾的空格,校验是否是合法的对象格式(以{开头、}结尾)。
  2. 遍历字符串内部内容,用计数器braceCount记录当前括号的层级:
    • 遇到{时计数器+1,遇到}时计数器-1。
    • 只有当计数器为0时,遇到的逗号才是外层键值对的分隔点。
  3. 分割出每个外层键值对后,找到第一个不在嵌套对象内的:,拆分键和值:
    • 清理键的前后空格得到键名。
    • 如果值以{开头,递归调用解析函数处理嵌套对象;否则清理空格作为普通值。

修正后的代码

function parseNestedObject(str) {
    // 清理首尾空格并校验格式
    const trimmedStr = str.trim();
    if (!trimmedStr.startsWith('{') || !trimmedStr.endsWith('}')) {
        throw new Error('输入不是有效的对象字符串');
    }

    const content = trimmedStr.slice(1, -1).trim();
    const result = {};
    let braceCount = 0;
    let currentKeyStart = 0;
    let keyValueSeparatorIndex = -1;

    for (let i = 0; i < content.length; i++) {
        const char = content[i];

        // 追踪括号层级
        if (char === '{') braceCount++;
        if (char === '}') braceCount--;

        // 仅在括号层级为0时,处理键值分隔符和外层逗号
        if (braceCount === 0) {
            if (char === ':') {
                keyValueSeparatorIndex = i;
            } else if (char === ',') {
                // 提取并处理当前键值对
                const key = content.slice(currentKeyStart, keyValueSeparatorIndex).trim();
                const value = content.slice(keyValueSeparatorIndex + 1, i).trim();
                
                result[key] = value.startsWith('{') 
                    ? parseNestedObject(value) 
                    : value;
                
                // 更新下一个键的起始位置
                currentKeyStart = i + 1;
                keyValueSeparatorIndex = -1;
            }
        }
    }

    // 处理最后一个没有逗号结尾的键值对
    if (keyValueSeparatorIndex !== -1) {
        const key = content.slice(currentKeyStart, keyValueSeparatorIndex).trim();
        const value = content.slice(keyValueSeparatorIndex + 1).trim();
        result[key] = value.startsWith('{') 
            ? parseNestedObject(value) 
            : value;
    }

    return result;
}

// 测试你的例子
const testString = '{dog : cat, joe: { jane: cat, peanut : dog }, fat : skinny}';
console.log(parseNestedObject(testString));
// 输出结果:{ dog: 'cat', joe: { jane: 'cat', peanut: 'dog' }, fat: 'skinny' }

这个版本完美解决了嵌套对象的解析问题,自动清理了空格,还加入了基本的输入校验,能处理你给出的测试用例,也能兼容更深层次的嵌套结构。

内容的提问来源于stack exchange,提问作者checkingJS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:41:24