当前位置: 首页 > news >正文

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

http://www.jsqmd.com/news/1370171/

相关文章:

  • NotePad++免费版编辑工具安装包百度网盘
  • 从字符串中提取 Document 的 page_content:手动拆还是用工具?
  • WebAssembly沙箱:为AI Agent构建安全高效执行环境的技术实践
  • 双向链表(头插、尾插、查找、修改、头删、尾删、删除指定节点、链表长度、销毁)
  • Claude Code 智能体架构解析:从任务规划到安全执行的AI编程伙伴
  • Unity UGUI性能优化:CanvasUpdateRegistry重建机制与实战分析
  • 无人机实训高成本痛点解法:虚拟仿真实现 70% 耗材损耗下降
  • 涛涛车业扩建泰国电动高尔夫球车与全地形车基地
  • Qoder Browser Use:为AI Agent打造可靠浏览器操作环境的技术解析与实践
  • 构建现代终端工作流:Alacritty、Zellij与Zinit的极客组合
  • 工程师必读:从Tokenization到Attention,深入理解LLM核心原理与工程实践
  • Matplotlib图表深度解析:从折线图到子图布局的Python数据可视化实战
  • Windows 10资源管理器卡死终极排查:从外壳扩展到系统文件的修复指南
  • 采购合同电子签有法律效力吗?供应商远程这样签最稳
  • SpringBoot+Vue博客系统集成协同过滤推荐算法实战
  • 涂胶显影行业中级工程师综合人才评估报告(六大核心维度)
  • Zabbix 5.0 从零部署指南:环境规划、安装配置与监控实战
  • Hive JSON解析性能优化:get_json_object与json_tuple函数深度对比与选型指南
  • Java守护线程:后台服务的生命周期管理与实战应用
  • Java技术栈的现状与转型实战指南
  • C++条件变量虚假唤醒:原理、解决方案与线程安全队列实战
  • NVIDIA NeMo Retriever:企业级多模态RAG框架实战指南
  • 技术面试中的防忽悠指南与实战案例分析
  • Python小提琴图实战:从核密度估计到数据洞察的完整指南
  • 从零自制全能游戏U盘:基于Batocera打造便携复古游戏系统
  • Open UI5键盘交互机制与优化实践
  • Claude Code多智能体协作:构建AI驱动的软件开发团队
  • 如何评估早期开源项目:从概念到可运行原型的系统性框架
  • 单片机全方位调试实战指南:串口/RTT/逻辑分析仪/示波器/内核排错分层避坑教程
  • DLNA投屏 | Windows无线投屏工具