从原始answer字符串中提取并解析JSON内容,支持处理尾部额外文本 返回:(解析后的字典, 字典keys列表)
(answer_raw)
| 383 | |
| 384 | return semantic_score,quality_score,rec_text ,final_correct_text |
| 385 | def parse_json_from_answer(answer_raw): |
| 386 | """ |
| 387 | 从原始answer字符串中提取并解析JSON内容,支持处理尾部额外文本 |
| 388 | 返回:(解析后的字典, 字典keys列表) |
| 389 | """ |
| 390 | # 1. 提取可能的JSON内容(处理不同包裹格式) |
| 391 | json_str = None |
| 392 | |
| 393 | # 优先匹配```json包裹的情况 |
| 394 | json_block_pattern = re.compile(r'```json\s*([\s\S]*?)\s*```', re.DOTALL) |
| 395 | match = json_block_pattern.search(answer_raw) |
| 396 | if match: |
| 397 | json_str = match.group(1).strip() |
| 398 | |
| 399 | # 若未匹配到,处理单/双引号包裹或无包裹的情况 |
| 400 | if not json_str: |
| 401 | processed = answer_raw.strip() |
| 402 | # 去除首尾匹配的单/双引号 |
| 403 | if (processed.startswith("'") and processed.endswith("'")) or \ |
| 404 | (processed.startswith('"') and processed.endswith('"')): |
| 405 | processed = processed[1:-1].strip() |
| 406 | json_str = processed |
| 407 | |
| 408 | # 检查是否提取到内容 |
| 409 | if not json_str: |
| 410 | assert False, "未提取到任何可能的JSON内容" |
| 411 | |
| 412 | # 2. 关键改进:截断JSON对象/数组后的额外文本(如Note、注释等) |
| 413 | # 处理JSON对象(以}结尾) |
| 414 | if '}' in json_str: |
| 415 | last_brace_idx = json_str.rfind('}') |
| 416 | json_str = json_str[:last_brace_idx + 1] # 保留到最后一个} |
| 417 | # 处理JSON数组(以]结尾) |
| 418 | elif ']' in json_str: |
| 419 | last_bracket_idx = json_str.rfind(']') |
| 420 | json_str = json_str[:last_bracket_idx + 1] # 保留到最后一个] |
| 421 | |
| 422 | # 3. 解析JSON(带错误处理) |
| 423 | first_e = None |
| 424 | # 第一次尝试直接解析 |
| 425 | try: |
| 426 | answer_dict = json.loads(json_str) |
| 427 | return answer_dict, list(answer_dict.keys()) |
| 428 | except json.JSONDecodeError as e: |
| 429 | first_e = e |
| 430 | |
| 431 | # 清理内部换行符(转为JSON兼容的\\n) |
| 432 | def replace_newlines(match): |
| 433 | inner = match.group(1) |
| 434 | return inner.replace('\n', '\\n').replace('\r', '\\r') |
| 435 | cleaned_str = re.sub(r'"([^"]*)"', lambda m: f'"{replace_newlines(m)}"', json_str) |
| 436 | |
| 437 | # 第二次尝试解析清理后的内容 |
| 438 | try: |
| 439 | answer_dict = json.loads(cleaned_str) |
| 440 | return answer_dict, list(answer_dict.keys()) |
| 441 | except json.JSONDecodeError as second_e: |
| 442 | error_msg = [ |
no test coverage detected