从原始answer字符串中提取并解析JSON内容,支持处理尾部额外文本 返回:(解析后的字典, 字典keys列表)
(answer_raw)
| 494 | def parse_json_from_answer(answer_raw): |
| 495 | """ |
| 496 | 从原始answer字符串中提取并解析JSON内容,支持处理尾部额外文本 |
| 497 | 返回:(解析后的字典, 字典keys列表) |
| 498 | """ |
| 499 | # 1. 提取可能的JSON内容(处理不同包裹格式) |
| 500 | json_str = None |
| 501 | |
| 502 | # 优先匹配```json包裹的情况 |
| 503 | json_block_pattern = re.compile(r'```json\s*([\s\S]*?)\s*```', re.DOTALL) |
| 504 | match = json_block_pattern.search(answer_raw) |
| 505 | if match: |
| 506 | json_str = match.group(1).strip() |
| 507 | |
| 508 | # 若未匹配到,处理单/双引号包裹或无包裹的情况 |
| 509 | if not json_str: |
| 510 | processed = answer_raw.strip() |
| 511 | # 去除首尾匹配的单/双引号 |
| 512 | if (processed.startswith("'") and processed.endswith("'")) or \ |
| 513 | (processed.startswith('"') and processed.endswith('"')): |
| 514 | processed = processed[1:-1].strip() |
| 515 | json_str = processed |
| 516 | |
| 517 | # 检查是否提取到内容 |
| 518 | if not json_str: |
| 519 | assert False, "未提取到任何可能的JSON内容" |
| 520 | |
| 521 | # 2. 关键改进:截断JSON对象/数组后的额外文本(如Note、注释等) |
| 522 | # 处理JSON对象(以}结尾) |
| 523 | if '}' in json_str: |
| 524 | last_brace_idx = json_str.rfind('}') |
| 525 | json_str = json_str[:last_brace_idx + 1] # 保留到最后一个} |
| 526 | # 处理JSON数组(以]结尾) |
| 527 | elif ']' in json_str: |
| 528 | last_bracket_idx = json_str.rfind(']') |
| 529 | json_str = json_str[:last_bracket_idx + 1] # 保留到最后一个] |
| 530 | |
| 531 | # 3. 解析JSON(带错误处理) |
| 532 | first_e = None |
| 533 | # 第一次尝试直接解析 |
| 534 | try: |
| 535 | answer_dict = json.loads(json_str) |
| 536 | return answer_dict, list(answer_dict.keys()) |
| 537 | except json.JSONDecodeError as e: |
| 538 | first_e = e |
| 539 | |
| 540 | # 清理内部换行符(转为JSON兼容的\\n) |
| 541 | def replace_newlines(match): |
| 542 | inner = match.group(1) |
| 543 | return inner.replace('\n', '\\n').replace('\r', '\\r') |
| 544 | cleaned_str = re.sub(r'"([^"]*)"', lambda m: f'"{replace_newlines(m)}"', json_str) |
| 545 | |
| 546 | # 第二次尝试解析清理后的内容 |
| 547 | try: |
| 548 | answer_dict = json.loads(cleaned_str) |
| 549 | return answer_dict, list(answer_dict.keys()) |
| 550 | except json.JSONDecodeError as second_e: |
| 551 | error_msg = [ |
| 552 | f"JSON解析失败(原始内容前50字符: {json_str[:50]}...)", |
| 553 | f"第一次错误: {str(first_e)}" if first_e else "", |
no test coverage detected