You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

64 lines
2.0 KiB

import json
class ContentManager:
def extract_json(self,s: str):
start = s.find('{')
if start < 0:
return None
depth = 0
for i, ch in enumerate(s[start:], start):
if ch == '{':
depth += 1
elif ch == '}':
depth -= 1
if depth == 0:
return s[start:i + 1]
return None # 没有闭合
def auto_complete_json(self,s: str) -> str:
"""
在字符串 s 中,自动检测未匹配的 { 并在末尾补全相应数量的 }。
返回补全后的新字符串。
"""
depth = 0
in_string = False
escape = False
for ch in s:
if escape:
escape = False
continue
if ch == '\\':
escape = True
continue
if ch == '"' and not escape:
in_string = not in_string
continue
if not in_string:
if ch == '{':
depth += 1
elif ch == '}':
if depth > 0:
depth -= 1
# depth 此时就是多余的 “{” 数量
if depth > 0:
s = s + '}' * depth
return s
def extract_and_fix_json(self,text: str):
"""
1. 找到首个 '{',然后尝试用 extract_json 的方式截取到末尾
2. 如果 extract_json 返回 None,就用 auto_complete_json 补全后再试一次 json.loads
"""
# 找到第一个 {
start = text.find('{')
if start < 0:
raise ValueError("字符串中没有发现 '{'")
fragment = text[start:]
# 先自动补全一次
fixed = self.auto_complete_json(fragment)
# 再尝试解析
try:
return json.loads(fixed)
except json.JSONDecodeError as e:
raise ValueError(f"补全后仍解析失败: {e}")