当前位置: 代码网 > it编程>前端脚本>Python > Python检查JSON格式错误的多种方法

Python检查JSON格式错误的多种方法

2026年02月15日 Python 我要评论
方法1:使用标准库json.loads()捕获异常(最常用)import jsondef validate_json(json_str): """ 验证json字符串格式是否正确 "

方法1:使用标准库json.loads()捕获异常(最常用)

import json

def validate_json(json_str):
    """
    验证json字符串格式是否正确
    """
    try:
        json.loads(json_str)
        return true, none
    except json.jsondecodeerror as e:
        return false, e

# 使用示例
test_cases = [
    '{"name": "张三", "age": 25}',  # 正确
    '{"name": "张三", "age": 25',   # 缺少右括号
    "{'name': '张三'}",             # 单引号错误
    '{"name": "张三", "age": }',    # 缺少值
]

for i, json_str in enumerate(test_cases):
    is_valid, error = validate_json(json_str)
    print(f"\n测试 {i+1}: {repr(json_str[:50])}")
    if is_valid:
        print("✓ json格式正确")
    else:
        print(f"✗ json格式错误: {error.msg}")
        print(f"  位置: 第{error.lineno}行, 第{error.colno}列")
        print(f"  上下文: {repr(error.doc[max(0, error.pos-20):error.pos+20])}")

方法2:详细的json错误诊断工具

import json
import re

class jsonvalidator:
    """json格式验证器,提供详细错误信息"""
    
    @staticmethod
    def validate(json_str, verbose=true):
        """
        验证json并返回详细信息
        """
        errors = []
        
        # 检查1: 是否为空
        if not json_str or not json_str.strip():
            errors.append("json字符串为空")
            return false, errors
        
        # 检查2: 尝试解析
        try:
            data = json.loads(json_str)
            return true, ["json格式正确"]
        except json.jsondecodeerror as e:
            errors.append(f"解析错误: {e.msg}")
            errors.append(f"位置: 行{e.lineno}, 列{e.colno}")
            errors.append(f"字符位置: {e.pos}")
            
            # 显示错误上下文
            context_start = max(0, e.pos - 30)
            context_end = min(len(json_str), e.pos + 30)
            context = json_str[context_start:context_end]
            errors.append(f"上下文: ...{context}...")
            
            # 标记错误位置
            marker = ' ' * (e.pos - context_start) + '^'
            errors.append(f"标记:   {marker}")
            
            # 检查3: 常见格式问题
            if "'" in json_str and '"' not in json_str:
                errors.append("警告: 检测到单引号,json应使用双引号")
            
            if json_str.startswith("'") or json_str.startswith('"'):
                # 检查是否有bom标记
                if json_str.startswith('\ufeff'):
                    errors.append("警告: 检测到bom标记")
            
            # 检查4: 括号匹配
            bracket_stack = []
            for i, char in enumerate(json_str):
                if char in '{[(':
                    bracket_stack.append((char, i))
                elif char in '}])':
                    if not bracket_stack:
                        errors.append(f"错误: 位置{i}处有未匹配的闭合括号'{char}'")
                        break
                    opening, pos = bracket_stack.pop()
                    if (opening == '{' and char != '}') or \
                       (opening == '[' and char != ']') or \
                       (opening == '(' and char != ')'):
                        errors.append(f"错误: 位置{pos}的'{opening}'与位置{i}的'{char}'不匹配")
            
            if bracket_stack:
                for opening, pos in bracket_stack:
                    errors.append(f"错误: 位置{pos}的'{opening}'没有闭合")
            
            return false, errors
    
    @staticmethod
    def pretty_print_errors(json_str):
        """
        美观地打印json错误信息
        """
        is_valid, errors = jsonvalidator.validate(json_str)
        
        print("=" * 60)
        print("json格式检查结果")
        print("=" * 60)
        print(f"输入: {repr(json_str[:100])}")
        print(f"状态: {'✓ 通过' if is_valid else '✗ 失败'}")
        print("-" * 60)
        
        for error in errors:
            print(f"  {error}")
        
        print("=" * 60)
        return is_valid

# 使用示例
if __name__ == "__main__":
    # 测试各种错误情况
    test_json = """
    {"name": "张三", "age": 25, "city": "北京"  # 缺少右括号
    """
    
    jsonvalidator.pretty_print_errors(test_json)
    
    print("\n" + "=" * 60)
    print("测试正确的json")
    print("=" * 60)
    correct_json = '{"name": "张三", "age": 25, "city": "北京"}'
    jsonvalidator.pretty_print_errors(correct_json)

方法3:逐行验证大json文件

import json

def validate_json_file(filepath):
    """
    验证json文件格式
    """
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            content = f.read()
            json.loads(content)
        print(f"✓ {filepath} 格式正确")
        return true
    except json.jsondecodeerror as e:
        print(f"✗ {filepath} 格式错误:")
        print(f"  错误: {e.msg}")
        print(f"  位置: 行{e.lineno}, 列{e.colno}")
        
        # 显示错误行
        with open(filepath, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            if e.lineno <= len(lines):
                print(f"  错误行: {e.lineno}: {lines[e.lineno-1].rstrip()}")
                # 标记错误位置
                marker = ' ' * (e.colno - 1) + '^'
                print(f"           {marker}")
        return false
    except filenotfounderror:
        print(f"✗ 文件不存在: {filepath}")
        return false

# 使用示例
# validate_json_file('data.json')

方法4:使用jsonschema验证json结构

import json
from jsonschema import validate, validationerror, schemaerror

def validate_json_structure(json_str, schema=none):
    """
    验证json结构是否符合预期
    """
    try:
        data = json.loads(json_str)
    except json.jsondecodeerror as e:
        return false, f"json格式错误: {e.msg}"
    
    # 如果提供了schema,验证结构
    if schema:
        try:
            validate(instance=data, schema=schema)
            return true, "json结构正确"
        except validationerror as e:
            return false, f"结构验证失败: {e.message}"
        except schemaerror as e:
            return false, f"schema错误: {e.message}"
    
    return true, "json格式正确"

# 使用示例
schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "number"},
        "email": {"type": "string", "format": "email"}
    },
    "required": ["name", "age"]
}

json_str = '{"name": "张三", "age": 25, "email": "zhangsan@example.com"}'
is_valid, message = validate_json_structure(json_str, schema)
print(f"{message}: {is_valid}")

方法5:命令行工具方式

# 保存为 validate_json.py
import json
import sys
import argparse

def main():
    parser = argparse.argumentparser(description='json格式验证工具')
    parser.add_argument('file', nargs='?', help='json文件路径')
    parser.add_argument('-s', '--string', help='json字符串')
    parser.add_argument('-v', '--verbose', action='store_true', help='详细输出')
    
    args = parser.parse_args()
    
    # 从文件或字符串读取
    if args.file:
        with open(args.file, 'r', encoding='utf-8') as f:
            json_str = f.read()
        source = f"文件: {args.file}"
    elif args.string:
        json_str = args.string
        source = "字符串"
    else:
        # 从stdin读取
        json_str = sys.stdin.read()
        source = "标准输入"
    
    # 验证
    try:
        data = json.loads(json_str)
        print(f"✓ {source}: json格式正确")
        if args.verbose:
            print(f"  类型: {type(data)}")
            if isinstance(data, dict):
                print(f"  键数量: {len(data)}")
            elif isinstance(data, list):
                print(f"  元素数量: {len(data)}")
        sys.exit(0)
    except json.jsondecodeerror as e:
        print(f"✗ {source}: json格式错误", file=sys.stderr)
        print(f"  错误: {e.msg}", file=sys.stderr)
        print(f"  位置: 行{e.lineno}, 列{e.colno}", file=sys.stderr)
        
        if args.verbose:
            # 显示上下文
            lines = json_str.split('\n')
            if e.lineno <= len(lines):
                print(f"\n  错误行 {e.lineno}:", file=sys.stderr)
                print(f"    {lines[e.lineno-1]}", file=sys.stderr)
                marker = ' ' * (e.colno - 1) + '^'
                print(f"    {marker}", file=sys.stderr)
        
        sys.exit(1)

if __name__ == '__main__':
    main()

使用方式:

# 验证文件
python validate_json.py data.json

# 验证字符串
python validate_json.py -s '{"name": "test"}'

# 详细模式
python validate_json.py -v data.json

# 从管道读取
echo '{"name": "test"}' | python validate_json.py

方法6:在线验证和格式化工具

如果不想写代码,可以使用这些工具:

  • jsonlint: https://jsonlint.com/
  • json formatter: https://jsonformatter.curiousconcept.com/
  • vs code插件: json相关插件

方法7:使用ide内置功能

vs code:

  • 安装 “json” 相关扩展
  • .json 文件自动验证
  • 快捷键: ctrl+space 提示

pycharm:

  • 内置json验证
  • 自动格式化: ctrl+alt+l
  • 语法高亮显示错误

实用调试技巧

import json
import traceback

def debug_json_error(json_str):
    """
    调试json错误的实用函数
    """
    print("=" * 70)
    print("json调试信息")
    print("=" * 70)
    print(f"长度: {len(json_str)} 字符")
    print(f"前100字符: {repr(json_str[:100])}")
    print(f"后100字符: {repr(json_str[-100:])}")
    
    # 检查常见问题
    checks = [
        ("是否为空", lambda s: not s.strip()),
        ("是否以单引号开头", lambda s: s.strip().startswith("'")),
        ("是否包含单引号", lambda s: "'" in s and '"' not in s),
        ("是否有bom标记", lambda s: s.startswith('\ufeff')),
        ("括号是否匹配", lambda s: s.count('{') != s.count('}') or s.count('[') != s.count(']')),
    ]
    
    print("\n初步检查:")
    for check_name, check_func in checks:
        result = check_func(json_str)
        status = "⚠ 可能有问题" if result else "✓ 正常"
        print(f"  {check_name}: {status}")
    
    # 尝试解析
    print("\n解析尝试:")
    try:
        data = json.loads(json_str)
        print(f"✓ 解析成功!")
        print(f"  类型: {type(data)}")
        if isinstance(data, dict):
            print(f"  键: {list(data.keys())[:5]}")
        return true
    except json.jsondecodeerror as e:
        print(f"✗ 解析失败!")
        print(f"  错误信息: {e.msg}")
        print(f"  位置: 行{e.lineno}, 列{e.colno}")
        
        # 显示详细上下文
        print(f"\n  错误位置上下文:")
        start = max(0, e.pos - 50)
        end = min(len(json_str), e.pos + 50)
        context = json_str[start:end]
        print(f"    ...{context}...")
        
        # 标记位置
        marker_pos = e.pos - start
        marker = ' ' * marker_pos + '^'
        print(f"    {' ' * (marker_pos)}{marker}")
        
        # 显示周围几行
        print(f"\n  周围行:")
        lines = json_str.split('\n')
        for i in range(max(0, e.lineno-2), min(len(lines), e.lineno+2)):
            prefix = "  > " if i == e.lineno-1 else "    "
            print(f"    {prefix}行{i+1}: {repr(lines[i][:100])}")
        
        return false
    finally:
        print("=" * 70)

# 使用示例
if __name__ == "__main__":
    # 测试有问题的json
    bad_json = '''
    {
        "name": "张三",
        'age': 25,  # 这里用了单引号
        "city": "北京"
    }
    '''
    
    debug_json_error(bad_json)

推荐方案总结

对于您的股票数据场景,建议使用:

import json
import logging

# 配置日志
logging.basicconfig(level=logging.info)
logger = logging.getlogger(__name__)

def safe_json_parse(data_str, source="未知来源"):
    """
    安全解析json,提供详细错误信息
    """
    try:
        return json.loads(data_str)
    except json.jsondecodeerror as e:
        logger.error(f"json解析失败 [{source}]:")
        logger.error(f"  错误: {e.msg}")
        logger.error(f"  位置: 行{e.lineno}, 列{e.colno}")
        logger.error(f"  上下文: {repr(data_str[max(0, e.pos-30):e.pos+30])}")
        
        # 尝试修复建议
        if "'" in data_str and '"' not in data_str:
            logger.warning("  建议: 检测到单引号,尝试使用 ast.literal_eval 或替换为双引号")
        
        raise

# 在您的代码中使用
try:
    data_dict = safe_json_parse(data_str, "redis")
    # 处理数据...
except json.jsondecodeerror:
    # 记录错误并跳过或使用默认值
    logger.error("跳过无效数据")
    continue

这样可以快速定位和修复json格式问题!

以上就是python检查json格式错误的多种方法的详细内容,更多关于python检查json格式错误的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com