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
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}")
|