news 2026/8/11 3:55:07

Python字符串转对象:从JSON到Document解析的三种实战场景

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python字符串转对象:从JSON到Document解析的三种实战场景

摘要

开发中经常遇到"看起来像列表/对象的字符串",怎么转成真正的Python对象?本文从三个场景展开:标准JSON字符串转列表、类列表字符串的安全解析、以及RAG项目中Document对象的元数据提取。读完即用。

一、场景一:标准JSON字符串转列表

这是最简单的情况。字符串本身就是合法的JSON数组。

python

import json raw_str = '["qwen-turbo","qwen-plus","deepseek"]' result = json.loads(raw_str) print(result) print(type(result))

输出:

text

['qwen-turbo', 'qwen-plus', 'deepseek'] <class 'list'>

json.loads()一步到位,干净利落。

也可以用ast.literal_eval

python

import ast raw_str = '["qwen-turbo","qwen-plus","deepseek"]' result = ast.literal_eval(raw_str)

ast.literal_eval更安全,只能解析合法的Python字面量,不会执行恶意代码。不过JSON格式用json.loads更标准。

二、场景二:看起来像列表但实际是对象的字符串

开发中常遇到这种数据——打印出来是[Document(...), Document(...)],看着像列表,实际是一个字符串,不能直接用json.loads解析。

比如RAG检索返回的Document列表被转成字符串打印到日志里:

python

raw_str = '[Document(metadata={"pk": 12, "page": 2}, page_content="内容1"), Document(metadata={"pk": 27, "page": 2}, page_content="内容2")]'

目标:提取每个Document的page属性。

解法:正则提取。

python

import re raw_str = '你的长字符串...' # 提取所有page值 pages = re.findall(r"'page':\s*(\d+)", raw_str) pages = [int(p) for p in pages] print(pages)

输出:

text

[2, 2, 3]

如果想同时提取pagepage_content

python

import re doc_pattern = r"Document\(metadata=\{([^}]+)\}, page_content='([^']*)'" matches = re.findall(doc_pattern, raw_str) for metadata, content in matches: page_match = re.search(r"'page':\s*(\d+)", metadata) if page_match: page = int(page_match.group(1)) print(f"page: {page}, content预览: {content[:50]}...")

关键点:这种字符串的本质是对象的repr()输出,不是标准序列化格式。正则是最直接的处理方式。

三、场景三:更复杂的Document字符串解析

如果字符串中page_content包含换行符、引号等特殊字符,情况会复杂一些。

比如:

python

raw_str = '[Document(metadata={"page": 1}, page_content="包含\'引号\'和\\n换行的内容")]'

简单正则可能匹配失败。这时可以分两步:

  1. 先按Document(分割

  2. 再用括号匹配提取内容

python

import re def extract_docs_from_str(raw_str): # 按Document(分割 parts = raw_str.split('Document(')[1:] results = [] for part in parts: # 找到metadata部分 meta_match = re.search(r"metadata=\{([^}]+)\}", part) if not meta_match: continue metadata_str = meta_match.group(1) page_match = re.search(r"'page':\s*(\d+)", metadata_str) page = int(page_match.group(1)) if page_match else None # 找到page_content部分(从第一个引号到最后一个引号) content_match = re.search(r"page_content='(.*)'\)?\s*$", part, re.DOTALL) if not content_match: content_match = re.search(r'page_content="(.*)"\)?\s*$', part, re.DOTALL) content = content_match.group(1) if content_match else "" results.append({"page": page, "content": content}) return results

注意:对于嵌套引号和转义字符,正则的健壮性有限。如果数据来源可控,建议在数据源头用json.dumps()pickle序列化,不要用repr()打印后再解析。

四、三种方案的对比

场景数据格式推荐方案
JSON数组["a","b"]json.loads()
Python字面量[1,2,3]{"a":1}ast.literal_eval()
对象repr输出[Document(...)]正则提取

五、踩坑提醒

1. 永远不要用eval()

python

# ❌ 危险:可能执行恶意代码 result = eval(raw_str)

eval()会执行字符串中的任意代码。如果数据来自外部输入,攻击者可以注入__import__('os').system('rm -rf /')之类的代码。

2. 区分字符串来源

  • 来自print()打印的对象 → 用正则

  • 来自json.dumps()→ 用json.loads()

  • 来自str(list)repr()→ 用正则或ast.literal_eval()(如果格式合法)

3. 单引号和双引号要统一

json.loads()要求双引号。如果字符串是单引号包裹的JSON,先用replace("'", '"')转换(但要注意内容里的引号不会误转)。

六、总结

方法适用场景安全性
json.loads()标准JSON安全
ast.literal_eval()Python字面量安全
正则提取对象repr输出安全
eval()不推荐任何场景危险

记住一句话:能用json.loads就用json.loads,不能用就上正则,永远别用eval

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/11 3:54:18

PowerShell实现Windows右下角Toast通知:从NotifyIcon到BurntToast实战

在 Windows 自动化运维或日常脚本开发中&#xff0c;我们经常需要向用户发送一些非阻塞的、轻量级的通知&#xff0c;比如任务完成提醒、状态更新或简单的警告。传统的弹窗&#xff08;如msgbox&#xff09;会强制用户交互&#xff0c;中断工作流&#xff0c;体验并不友好。而系…

作者头像 李华
网站建设 2026/8/11 3:52:46

开源设计工具Open Design:可视化生成React/Vue代码,提升前端开发效率

1. 项目概述&#xff1a;从“求人”到“自主”的设计能力跃迁最近在技术社区和产品经理圈子里&#xff0c;一个话题的热度居高不下&#xff1a;如何快速、低成本地获得高质量的UI/UX设计产出&#xff0c;尤其是当团队里没有专职设计师&#xff0c;或者前端开发资源紧张的时候。…

作者头像 李华
网站建设 2026/8/11 3:52:04

OpenClaw自动化任务定时执行:从Cron表达式到生产部署全指南

1. 从“手动触发”到“无人值守”的进化做自动化工具&#xff0c;最爽的时刻是什么&#xff1f;不是第一次成功运行&#xff0c;而是你把它配置好&#xff0c;然后彻底忘了它&#xff0c;过段时间一看&#xff0c;它已经默默帮你处理了一堆任务。这就是“无人值守”的魅力。Ope…

作者头像 李华
网站建设 2026/8/11 3:48:41

QGroundControl 5.0 安卓开发环境搭建实战:从零编译到成功运行

最近准备把地面站项目升级到 QGroundControl 5.0&#xff0c;于是重新搭建了一套 Android 开发环境。原本以为和 QGC 4.x 差不多&#xff0c;结果一上来就连续踩坑&#xff1a;Qt版本不匹配Android Kit不显示NDK版本错误Gradle构建失败折腾了几个小时后终于成功编译并运行在安卓…

作者头像 李华
网站建设 2026/8/11 3:47:30

大气层系统深度技术指南:从源码结构到高级配置的完全解析

大气层系统深度技术指南&#xff1a;从源码结构到高级配置的完全解析 【免费下载链接】Atmosphere-stable 大气层整合包系统稳定版 项目地址: https://gitcode.com/gh_mirrors/at/Atmosphere-stable 大气层系统&#xff08;Atmosphere&#xff09;是一个为Nintendo Swit…

作者头像 李华