Python 解析“长得像 list 的 Document 字符串“:

📅 2026/8/11 3:34:29
Python 解析“长得像 list 的 Document 字符串“:
Python 解析长得像 list 的 Document 字符串提取 page 并拼接别再无脑 eval这是字符串转 list 系列的第 2 题。第 1 题里字符串是标准的 JSON / Python 列表用json.loads/ast.literal_eval就能解决。但这一题的字符串不是普通列表而是一堆Document(...)——它是 LangChain 里Document对象的字符串表示repr目标取出每个 Document 的page页码并把每页的page_content正文拼接起来。一、为什么第 1 题的方法在这里全部失效这个字符串里既有单引号又有Document(metadata..., page_content...)这种函数调用写法它既不是 JSON也不是 Python 字面量所以第 1 题那套在这里直接报废。二、最稳的解法正则提取不碰 eval最安全既然字符串格式是固定的Document(metadata{...}, page_content...)我们用正则只解析结构不执行任何代码。这样无论来源是否可信都很安全。思路用正则找出每一段Document(...)抓出它的metadata{...}和page_content...从 metadata 里取page: 数字把每段的page_content收集起来按需拼接。✅优点纯正则、零执行、对任意来源都安全不关心page_content里有什么奇怪字符只认结构。 小提示如果原始字符串里的\n是被转义过的\\n两个字符提取出来的是字面量换行符。想要真正的换行拼接前加一句三、拼接时想按页码排序怎么办默认parse_documents是按字符串里出现的顺序返回的。如果你希望结果按page从小到大排四、如果你完全掌控来源用 eval 重建真实 Document如果这段字符串确定是你自己代码print/repr出来的绝对不会被外部篡改也可以直接把它变回真正的Document对象然后像平时一样用.metadata[page]访问⚠️为什么说一般不推荐eval会执行字符串里的任意 Python 代码。一旦这段字符串来自用户、接口、数据库等外部输入别人塞一句__import__(os).system(rm -rf /)就能造成破坏。而且page_content里的转义字符\n会被eval当成真换行解析行为取决于字符串来源不可控。五、正确的设计别把 Document 存成 repr 字符串Document的repr只是给人看的调试输出不是稳定的序列化格式。如果你要持久化或传输 Documents请用 JSON / pickle这样以后无论是取page、拼正文还是存数据库都规规矩矩不用再跟repr字符串斗智斗勇。六、三种方式对比方式安全性是否需可信来源适用场景正则提取推荐高否只能拿到字符串、来源不可信或不想引依赖eval重建 Document低代码注入是你 100% 信任这段 repr 字符串、临时调试JSON 序列化 / 反序列化高否从设计上就该这么存/传根本不该出现 repr 字符串七、总结字符串里是Document(metadata..., page_content...)这种repr不是 JSON / 字面量json.loads/ast.literal_eval都救不了首选正则提取抓metadata里的page和page_content安全又稳需要真实Document对象且来源可信时可用eval但务必清楚它的注入风险治本办法从一开始就用json.dumps序列化 Document而不是把repr当数据存。一句话拿 page、拼正文用正则想省事又安全从源头改用 JSON。