pandas json_normalize导出Excel单引号致JS JSON.parse失败问题求解
解决方案
Pandas侧根治方案(优先选用)
问题根源是pandas导出Excel时,会直接调用Python原生str()方法序列化嵌套的列表、字典对象,输出的是Python字面量格式,不符合JSON语法规范。不需要在前端做字符串修补,直接在导出前将嵌套结构序列化为标准JSON字符串即可彻底解决问题:
- 提前导入Python内置
json模块 - 写入Excel前,遍历所有存储了列表、字典类型数据的列,对列内每个元素调用
json.dumps()转为标准JSON格式字符串,设置ensure_ascii=False避免中文等非ASCII字符被转义 - 处理后写入Excel的内容本身就是合法JSON,JS端读取后直接调用
JSON.parse()即可解析,内容里的撇号、特殊符号都会被自动正确转义,完全不会出现格式错误
参考实现代码:
import json import pandas as pd with pd.ExcelWriter(parameters['path']) as writer: df = pd.json_normalize(features) # 处理所有存了嵌套对象/数组的列 for col in df.columns: sample_val = df[col].dropna().iloc[0] if not df[col].dropna().empty else None if isinstance(sample_val, (list, dict)): df[col] = df[col].apply(lambda x: json.dumps(x, ensure_ascii=False) if pd.notna(x) else x) df.to_excel(writer, sheet_name="test", index=False)
原生JavaScript侧兜底方案
如果无法修改pandas导出逻辑,必须处理已生成的非标准格式字符串,不要用全局替换单引号的方式,用逐字符状态扫描的方式做转换即可,不会破坏字符串内部的撇号内容,无任何第三方依赖:
- 逐字符遍历待解析字符串,维护「是否处于字符串内部」的状态标记
- 仅将作为字符串边界的引号(不管原先是单引号还是双引号)统一替换为JSON要求的双引号
- 字符串内部的所有引号、特殊符号全部原封不动保留,避免破坏
St. Mary's这类带撇号的文本 - 转换完成的字符串直接传入
JSON.parse()即可得到标准JS对象
参考实现代码:
function parsePythonLiteral(str) { const chars = []; let inString = false; let boundaryQuote = ''; let escaped = false; for (const c of str) { if (escaped) { chars.push(c); escaped = false; continue; } if (c === '\\') { chars.push(c); escaped = true; continue; } if (c === '"' || c === "'") { if (!inString) { inString = true; boundaryQuote = c; chars.push('"'); } else if (c === boundaryQuote) { inString = false; boundaryQuote = ''; chars.push('"'); } else { chars.push(c); } continue; } chars.push(c); } // 如果数据里存在Python的布尔值、空值,可放开下面几行注释做适配 // let jsonStr = chars.join('') // .replace(/: True/g, ': true') // .replace(/: False/g, ': false') // .replace(/: None/g, ': null'); // return JSON.parse(jsonStr); return JSON.parse(chars.join('')); } // 调用示例 const rawStr = "[{'url' : 'https://foo', 'title' : \"St. Mary's Church\"}]"; const parsed = parsePythonLiteral(rawStr);
注意:该兜底方案仅适配常规结构的列表、字典字符串,优先使用Pandas侧预处理方案,稳定性更高。
内容的提问来源于stack exchange,提问作者CitizenFish
相关产品推荐
相关产品推荐

