python修复json神器:json-repair包(用于大模型返回json不规范)

文章目录

一、简介

文档:https://pypi.org/project/json-repair/

(文末有其他语言修复链接)

bash 复制代码
# 安装
pip install json-repair

1、简介

它可以:

(1)修复JSON中的语法错误

缺少引号、逗号位置错误、有未转义的字符以及键值对不完整。

缺少引号、格式错误的值(true、false、null),以及修复损坏的键值结构。

(2)修复格式错误的JSON数组和对象

不完整或损坏的数组/对象,可通过添加必要的元素(如逗号、括号)或默认值(null、"")来修复。

该库能够处理包含额外非JSON字符的JSON数据,如注释或位置错误的字符,并在保持有效结构的同时清除这些字符。

(3)缺失JSON值的自动补全

自动用合理的默认值(如空字符串或null)填充JSON字段中的缺失值,以确保数据的有效性。

二、使用

1、三种使用方式

py 复制代码
from json_repair import repair_json
# 将坏的json字符串修复为好的字符串,如果是单纯的字符串,则返回空串
good_json_string = repair_json(bad_json_string)
py 复制代码
import json_repair
# 你可以使用这个库来完全替代json.loads():
decoded_object = json_repair.loads(json_string)
py 复制代码
import json_repair
# True是直接返回对象,而不是json字符串
decoded_object = json_repair.repair_json(json_string, return_objects=True)

(示例)示例

py 复制代码
# 用于llm返回json格式,用于修复
# pip install json-repair

import json
from json_repair import repair_json

# 1、 broken_json = "{'name': 'Alice', 'age': 20}" # 有问题的JSON(单引号)
# 2、 broken_json = '[1, 2, 3, ]'  # 数组末尾多余逗号
'''
#3、 修复注释
broken_json = """
{
    // 这是一条注释
    "id": 123,
    "desc": "test"  /* 这是另一条注释 */
}
"""
'''
#4、 llm按照json格式返回有问题:
bad_json_string = '你好,这是我按照json格式返回的数据:{"name": "John", "age": 30, "city": "New York'
# 修复json字符串
good_json_string = repair_json(bad_json_string)
print(good_json_string)
# 解析修复后的json
data = json.loads(good_json_string)
print(data)

2、开发误区

一些使用该库的用户采用以下模式:

这是浪费资源的行为,因为json_repair会自动验证JSON是否有效。如果你仍想进行验证,可以按照下文的说明在调用中添加skip_json_loads=True。

py 复制代码
obj = {}
try:
    obj = json.loads(string)
except json.JSONDecodeError as e:
    obj = json_repair.loads(string)
    ...

3、从文件或文件描述符中读取JSON数据

JSON修复功能也可直接替代json.load():

py 复制代码
import json_repair

try:
    file_descriptor = open(fname, 'rb')
except OSError:
    ...

with file_descriptor:
    decoded_object = json_repair.load(file_descriptor)

请注意,库无法捕获任何与输入/输出相关的异常,这些异常需要由您自行处理。

py 复制代码
import json_repair
# 更简洁的方式
try:
    decoded_object = json_repair.from_file(json_file)
except OSError:
    ...
except IOError:
    ...

4、非拉丁字符处理

在处理非拉丁字符(如中文、日文或韩文)时,需要将ensure_ascii=False传递给repair_json(),这样才能在输出结果中保留非拉丁字符。

py 复制代码
# 示例:
repair_json("{'test_chinese_ascii':'统一码'}")
# 将会返回
{"test_chinese_ascii": "\u7edf\u4e00\u7801"}

# 而不是选择ensure_ascii=False:
repair_json("{'test_chinese_ascii':'统一码'}", ensure_ascii=False)
# 将会返回
{"test_chinese_ascii": "统一码"}

5、提升性能

如果你觉得这个库因为使用了json.loads()而运行太慢,可以通过将skip_json_loads=True传递给repair_json来跳过该步骤。例如:

py 复制代码
from json_repair import repair_json

good_json_string = repair_json(bad_json_string, skip_json_loads=True)

设置return_objects=True总是更快,因为解析器会直接返回一个对象,无需将该对象序列化为JSON格式。
skip_json_loads 只有在你百分百确定该字符串不是有效 JSON 时才更快。

如果你在转义字符串时遇到问题,可以将其作为原始字符串传递,例如:r"string with escaping\""

6、严格模式

默认情况下,json_repair会尽力"修复"输入数据,即使JSON格式完全无效。

在某些情况下,你需要相反的行为,即让解析器报错而不是尝试修复数据。此时可以将strict=True传递给repair_json、loads、load或from_file来启用该模式:

py 复制代码
from json_repair import repair_json

repair_json(bad_json_string, strict=True)

CLI在使用json_repair --strict input.json时表现出相同的行为(或通过stdin传输数据)。

在严格模式下,解析器一旦遇到重复键、缺失的分隔符、因多余的逗号导致的空键/值对、多个顶级元素或其他模糊结构等问题,就会抛出ValueError错误。当您只需要友好的错误提示来进行验证时,这种模式非常实用,同时您仍可以在代码的其他部分利用json_repair的强大修复功能。

严格模式仍然遵循skip_json_loads=True规则;将两者结合使用可跳过初始的json.loads检查,同时仍能执行严格的解析规则。

7、使用 json_repair 进行流式修复

有时你在传输数据时,需要修复传入的JSON格式。通常情况下这行不通,但你可以将stream_stable传递给repair_json()或loads(),这样就能实现修复功能了:

py 复制代码
stream_output = repair_json(stream_input, stream_stable=True)

8、使用 CLI 中的 json_repair

py 复制代码
# 查看帮助
$ json_repair -h
usage: json_repair [-h] [-i] [-o TARGET] [--ensure_ascii] [--indent INDENT]
                   [--skip-json-loads] [--schema SCHEMA] [--schema-model MODEL]
                   [--strict] [filename]

Repair and parse JSON files.

positional arguments:
  filename              The JSON file to repair (if omitted, reads from stdin)

options:
  -h, --help            show this help message and exit
  -i, --inline          Replace the file inline instead of returning the output to stdout
  -o TARGET, --output TARGET
                        If specified, the output will be written to TARGET filename instead of stdout
  --ensure_ascii        Pass ensure_ascii=True to json.dumps()
  --indent INDENT       Number of spaces for indentation (Default 2)
  --skip-json-loads     Skip initial json.loads validation
  --schema SCHEMA       Path to a JSON Schema file that guides repairs
  --schema-model MODEL  Pydantic v2 model in 'module:ClassName' form that guides repairs
  --strict              Raise on duplicate keys, missing separators, empty keys/values, and similar structural issues instead of repairing them

三、Java版本

修复json,其他包都没有这个修复的好!

xml 复制代码
        <dependency>
            <groupId>io.github.du00cs</groupId>
            <artifactId>json-repairj</artifactId>
            <version>0.50.0</version>
        </dependency>

1、使用

java 复制代码
import org.jsonrepairj.JsonRepair;
import org.jsonrepairj.ParseResult;

public class Test {

    public static void main(String[] args) {

        String str = "你好,这是我按照json格式返回的数据:{\"name\": \"约翰\", \"age\": 30, \"city\": \"New York";
        // 修复json  {"name":"约翰","age":30,"city":"New York"}
        String result = JsonRepair.repairJson(str);
        System.out.println(result);

// or more control (result = jackson node + warnings)
        ParseResult result2 = JsonRepair.parseJson(str, true, false);
        System.out.println(result2.getJson().toString());
    }
}
相关推荐
yuanmenghao2 小时前
Linux 性能实战 | 第 20 篇:trace-cmd 与 kernelshark 可视化分析 [特殊字符]
linux·python·性能优化
FoldWinCard2 小时前
Python 第三次作业
java·服务器·python
0思必得03 小时前
[Web自动化] Selenium浏览器复用
前端·python·selenium·自动化
-小麦子-3 小时前
Python 变量组包、解包及星号扩展机制详解
开发语言·python
Jia ming3 小时前
编程思维VS法律思维:Python教学双轨制
python·教学
赵谨言3 小时前
运用Python编程计算减压孔板孔口直径的研究
大数据·开发语言·经验分享·python
njsgcs3 小时前
用python打开exe 不闪退 0x01000000 # CREATE_BREAKAWAY_FROM_JOB
开发语言·python
橙露3 小时前
全栈开发入门:Python Flask+Vue3 搭建前后端分离的博客系统
开发语言·python·flask