层级文本转JSON对象:简易编译器开发及代码实现问询
层级文本转JSON编译器实现方案与优化指导
核心思路
这类转换的核心是识别缩进层级,通过栈结构维护当前节点的父级关系,将每一行解析为对应层级的键值对或数组元素,最终递归生成JSON结构。
明确解析规则(基于通用层级文本规范)
- 缩进代表层级:以2空格为1级(可自定义),缩进越多层级越深
- 键值对格式:
键: 值,值支持字符串、数字、布尔值 - 数组项:以
-开头的行表示数组元素,元素可包含子节点 - 忽略内容:空行、以
//开头的注释行
优化后的实现代码
class Chunk { constructor(level, key, value, isArrayItem = false) { this.level = level; this.key = key; this.value = value; this.children = []; this.isArrayItem = isArrayItem; } // 递归转换为JSON结构 toJSON() { if (this.isArrayItem) { return this.children.length > 0 ? this.children.reduce((obj, child) => { obj[child.key] = child.toJSON(); return obj; }, {}) : this.value; } const result = {}; if (this.value !== undefined) { result[this.key] = this.value; } else { this.children.forEach(child => { if (child.isArrayItem) { if (!result[this.key]) result[this.key] = []; result[this.key].push(child.toJSON()); } else { result[child.key] = child.toJSON(); } }); } return result; } } function parseHierarchicalText(text) { // 预处理:拆分行、过滤无效行 const lines = text.split('\n') .map(line => line.trimEnd()) .filter(line => !line.startsWith('//') && line.trim() !== ''); const root = new Chunk(-1, 'root'); const stack = [root]; lines.forEach(line => { // 计算当前层级 const indentMatch = line.match(/^(\s*)/)[1]; const level = indentMatch.length / 2; const content = line.trim(); // 解析行内容:区分数组项和普通键值对 let isArrayItem = false; let key, value; if (content.startsWith('- ')) { isArrayItem = true; const itemContent = content.slice(2).trim(); if (itemContent.includes(': ')) { [key, value] = itemContent.split(': ', 2); value = parseValue(value); } else { key = '__temp__'; value = parseValue(itemContent); } } else { [key, value] = content.split(': ', 2); value = parseValue(value); } // 找到当前层级的父节点 while (stack.length > 0 && stack[stack.length - 1].level >= level) { stack.pop(); } const parent = stack[stack.length - 1]; const chunk = new Chunk(level, key, value, isArrayItem); parent.children.push(chunk); stack.push(chunk); }); // 生成最终JSON对象 return root.children.reduce((obj, child) => { if (child.isArrayItem) { obj[child.key.replace('__temp__', 'features')] = [child.toJSON()]; } else { obj[child.key] = child.toJSON(); } return obj; }, {}); } // 辅助函数:自动转换值类型 function parseValue(str) { if (!isNaN(str) && str.trim() !== '') return Number(str); if (str.toLowerCase() === 'true') return true; if (str.toLowerCase() === 'false') return false; if (str.startsWith('"') && str.endsWith('"')) return str.slice(1, -1); return str; } // 示例调用 const inputText = ` name: "My Project" description: A simple hierarchical text to JSON compiler settings: theme: dark notifications: true maxItems: 10 features: - name: Syntax Highlighting enabled: true - name: Auto Save enabled: false - Quick Export `; console.log(JSON.stringify(parseHierarchicalText(inputText), null, 2));
关键优化点
- Chunk类增强:新增
isArrayItem标识,明确区分数组项与普通节点,简化递归转换逻辑 - 层级处理:用栈结构精准维护父节点关系,避免层级挂载错误
- 值类型自动转换:通过
parseValue实现字符串到数字、布尔值的自动转换,提升JSON结构的准确性 - 无效内容过滤:提前过滤空行和注释,减少无效解析操作
测试输出示例
{ "name": "My Project", "description": "A simple hierarchical text to JSON compiler", "settings": { "theme": "dark", "notifications": true, "maxItems": 10 }, "features": [ { "name": "Syntax Highlighting", "enabled": true }, { "name": "Auto Save", "enabled": false }, "Quick Export" ] }
扩展建议
- 支持Tab缩进:修改
level计算逻辑为indentMatch.split('\t').length - 1 - 嵌套数组支持:当前实现已兼容,只需在数组项内继续缩进添加子节点
- 多行字符串:可新增规则(如用
"""包裹),在parseValue中处理跨行内容
内容的提问来源于stack exchange,提问作者MrFrontend
相关产品推荐
相关产品推荐

