最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python解析不規(guī)則JSON數(shù)據(jù)的實(shí)戰(zhàn)技巧

 更新時(shí)間:2026年01月27日 09:39:52   作者:大黃評(píng)測(cè)  
在真實(shí)世界的數(shù)據(jù)處理中,我們很少遇到教科書(shū)式的標(biāo)準(zhǔn)?JSON,文將為你提供一套從溫和修復(fù)到強(qiáng)力解析的完整工具箱,用?Python?輕松馴服這些野性數(shù)據(jù),有需要的小伙伴可以了解下

在真實(shí)世界的數(shù)據(jù)處理中,我們很少遇到教科書(shū)式的標(biāo)準(zhǔn) JSON。更多時(shí)候,面對(duì)的是:

  • 單引號(hào)代替雙引號(hào)
  • 末尾多出逗號(hào)
  • 鍵名未加引號(hào)(如 {name: "Alice"}
  • 混合了注釋?zhuān)?code>// 這是注釋)
  • 嵌套結(jié)構(gòu)缺失或類(lèi)型錯(cuò)亂(字符串里藏了 JSON 片段)
  • 甚至根本不是合法 JSON,而是 JavaScript 對(duì)象字面量(JS Object Literal)

這類(lèi)“不規(guī)則 JSON”無(wú)法被 Python 內(nèi)置的 json.loads() 直接解析,強(qiáng)行使用會(huì)拋出 JSONDecodeError。但別急——本文將為你提供一套從溫和修復(fù)到強(qiáng)力解析的完整工具箱,用 Python 輕松馴服這些“野性”數(shù)據(jù)。

一、場(chǎng)景1:輕微格式錯(cuò)誤(單引號(hào)、尾逗號(hào)等)

典型數(shù)據(jù)

{
  'name': 'Alice',
  'age': 30,
  'tags': ['a', 'b',],
}

解法:使用ast.literal_eval(僅限 Python 字面量)

如果數(shù)據(jù)本質(zhì)是 Python 字典/列表字面量(而非嚴(yán)格 JSON),可嘗試:

import ast

dirty_str = "{'name': 'Alice', 'age': 30, 'tags': ['a', 'b',]}"
try:
    data = ast.literal_eval(dirty_str)
    print(data)  # {'name': 'Alice', 'age': 30, 'tags': ['a', 'b']}
except (ValueError, SyntaxError) as e:
    print("無(wú)法解析為 Python 字面量")

注意:ast.literal_eval 只支持 str, bytes, int, float, list, dict, tuple, bool, None,不支持 NaNInfinity 等。

二、場(chǎng)景2:含注釋、尾逗號(hào)、鍵無(wú)引號(hào)(類(lèi) JS 對(duì)象)

典型數(shù)據(jù)

{
  // 用戶(hù)信息
  name: "Bob",
  age: 25,
  hobbies: [
    "coding",
    "gaming",  // 末尾逗號(hào)
  ],
}

解法:使用json5庫(kù)(推薦?。?/strong>

JSON5 是 JSON 的擴(kuò)展,支持注釋、單引號(hào)、尾逗號(hào)、無(wú)引號(hào)鍵等,完美兼容 JavaScript 風(fēng)格對(duì)象。

安裝:

pip install json5

使用:

import json5

with open('config.js', 'r', encoding='utf-8') as f:
    data = json5.load(f)  # 或 json5.loads(string)

print(data['name'])  # Bob

優(yōu)點(diǎn):安全、標(biāo)準(zhǔn)、廣泛用于前端配置文件(如 .babelrc, tsconfig.json 變體)。

三、場(chǎng)景3:字符串中嵌套未轉(zhuǎn)義的 JSON 片段

典型數(shù)據(jù)

{
  "log": "User {"id": 123, "action": "login"} performed"
}

你可能想提取內(nèi)部的 {"id": 123, ...},但它被包裹在字符串中。

解法:正則 + 遞歸解析

import json
import re

def extract_and_parse_nested_json(text):
    # 匹配最外層的 {...},但需確保是完整 JSON 對(duì)象
    pattern = r'{(?:[^{}]|(?R))*}'  # 遞歸正則(Python 不支持 (?R),改用循環(huán))
    
    # 更穩(wěn)健的做法:逐字符掃描括號(hào)匹配
    def find_outer_braces(s):
        stack = 0
        start = -1
        for i, c in enumerate(s):
            if c == '{':
                if stack == 0:
                    start = i
                stack += 1
            elif c == '}':
                stack -= 1
                if stack == 0 and start != -1:
                    return s[start:i+1]
        return None

    nested = find_outer_braces(text)
    if nested:
        try:
            return json.loads(nested)
        except json.JSONDecodeError:
            return None
    return None

log_str = 'User {"id": 123, "action": "login"} performed'
inner = extract_and_parse_nested_json(log_str)
print(inner)  # {'id': 123, 'action': 'login'}

四、場(chǎng)景4:完全非結(jié)構(gòu)化,但有規(guī)律可循

比如日志文件中的混合內(nèi)容:

INFO: {user: "Tom", status: ok}
ERROR: Failed to parse {data: [1,2,,3]}

解法:先用正則提取疑似 JSON 片段,再用容錯(cuò)解析器

結(jié)合 json5 + 異常捕獲:

import json5
import re

log_line = 'ERROR: Failed to parse {data: [1,2,,3]}'

# 提取花括號(hào)包圍的內(nèi)容
match = re.search(r'{.*}', log_line)
if match:
    candidate = match.group()
    try:
        data = json5.loads(candidate)
        print("Parsed:", data)
    except Exception as e:
        print("Still invalid:", e)

提示:對(duì)于 [, ,] 這類(lèi)空元素,json5 也支持(視為 null)。

五、終極武器:自定義解析器 or LLM 輔助(慎用)

若數(shù)據(jù)極度混亂(如混合 HTML、自定義 DSL),可考慮:

  • 使用 lark、ply 構(gòu)建自定義語(yǔ)法解析器;
  • 用大模型(如本地 LLM)將“臟數(shù)據(jù)”重寫(xiě)為合法 JSON(適合低頻、高價(jià)值場(chǎng)景)。

但絕大多數(shù)情況,json5 + 正則清洗 + 異常處理 已足夠覆蓋。

最佳實(shí)踐建議

  • 優(yōu)先用 json5:它能解決 90% 的“類(lèi) JSON”問(wèn)題;
  • 不要用 eval() :極其危險(xiǎn),可能執(zhí)行任意代碼;
  • 記錄解析失敗樣本:用于后續(xù)規(guī)則優(yōu)化;
  • 在數(shù)據(jù)入口 做標(biāo)準(zhǔn)化:若可控,推動(dòng)上游輸出合法 JSON。

結(jié)語(yǔ)

不規(guī)則 JSON 不是“錯(cuò)誤”,而是現(xiàn)實(shí)世界的常態(tài)。Python 生態(tài)提供了從輕量級(jí)(ast)到工業(yè)級(jí)(json5)的多種工具,關(guān)鍵在于識(shí)別數(shù)據(jù)“臟”在哪一層,然后選擇匹配的清洗策略。

記?。?strong>解析不是目的,可靠地獲取結(jié)構(gòu)化信息才是。用對(duì)工具,那些看似混亂的字符串,終將成為你數(shù)據(jù)管道中的清晰字段。

到此這篇關(guān)于Python解析不規(guī)則JSON數(shù)據(jù)的實(shí)戰(zhàn)技巧的文章就介紹到這了,更多相關(guān)Python解析JSON數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

兴宁市| 丹凤县| 大渡口区| 阳谷县| 昂仁县| 灵武市| 内江市| 洪湖市| 宣城市| 息烽县| 南城县| 尚志市| 库尔勒市| 芒康县| 长岛县| 萨嘎县| 乌审旗| 连城县| 托克逊县| 阳东县| 江油市| 双江| 连平县| 威信县| 长宁区| 灌云县| 安福县| 弋阳县| 郓城县| 正安县| 太康县| 石泉县| 朝阳县| 兖州市| 黎平县| 吉木萨尔县| 开原市| 百色市| 乌苏市| 南宫市| 常州市|