# chapter_blueprint_parser.py # -*- coding: utf-8 -*- import re def parse_chapter_blueprint(blueprint_text: str): """ 解析整份章节蓝图文本,返回一个列表,每个元素是一个 dict: { "chapter_number": int, "chapter_title": str, "chapter_role": str, # 本章定位 "chapter_purpose": str, # 核心作用 "suspense_level": str, # 悬念密度 "foreshadowing": str, # 伏笔操作 "plot_twist_level": str, # 认知颠覆 "chapter_summary": str # 本章简述 } """ # 先按空行进行分块,以免多章之间混淆 chunks = re.split(r'\n\s*\n', blueprint_text.strip()) results = [] chapter_number_pattern = re.compile(r'^第\s*(\d+)\s*章\s*-\s*\[(.*?)\]') # 捕获章号与标题 role_pattern = re.compile(r'^本章定位:\s*(.*)$') purpose_pattern = re.compile(r'^核心作用:\s*(.*)$') suspense_pattern = re.compile(r'^悬念密度:\s*(.*)$') foreshadow_pattern = re.compile(r'^伏笔操作:\s*(.*)$') twist_pattern = re.compile(r'^认知颠覆:\s*(.*)$') summary_pattern = re.compile(r'^本章简述:\s*\[(.*)\]$') for chunk in chunks: lines = chunk.strip().splitlines() if not lines: continue chapter_number = None chapter_title = "" chapter_role = "" chapter_purpose = "" suspense_level = "" foreshadowing = "" plot_twist_level = "" chapter_summary = "" # 先匹配第一行(或前几行),找到章号和标题 header_match = chapter_number_pattern.match(lines[0].strip()) if lines else None if not header_match: # 不符合格式,跳过 continue chapter_number = int(header_match.group(1)) chapter_title = header_match.group(2).strip() # 从后面的行匹配其他字段 for line in lines[1:]: line_stripped = line.strip() if not line_stripped: continue m_role = role_pattern.match(line_stripped) if m_role: chapter_role = m_role.group(1).strip() continue m_purpose = purpose_pattern.match(line_stripped) if m_purpose: chapter_purpose = m_purpose.group(1).strip() continue m_suspense = suspense_pattern.match(line_stripped) if m_suspense: suspense_level = m_suspense.group(1).strip() continue m_foreshadow = foreshadow_pattern.match(line_stripped) if m_foreshadow: foreshadowing = m_foreshadow.group(1).strip() continue m_twist = twist_pattern.match(line_stripped) if m_twist: plot_twist_level = m_twist.group(1).strip() continue m_summary = summary_pattern.match(line_stripped) if m_summary: chapter_summary = m_summary.group(1).strip() continue results.append({ "chapter_number": chapter_number, "chapter_title": chapter_title, "chapter_role": chapter_role, "chapter_purpose": chapter_purpose, "suspense_level": suspense_level, "foreshadowing": foreshadowing, "plot_twist_level": plot_twist_level, "chapter_summary": chapter_summary }) # 按照 chapter_number 排序后返回 results.sort(key=lambda x: x["chapter_number"]) return results def get_chapter_info_from_blueprint(blueprint_text: str, target_chapter_number: int): """ 在已经加载好的章节蓝图文本中,找到对应章号的结构化信息,返回一个 dict。 若找不到则返回一个默认的结构。 """ all_chapters = parse_chapter_blueprint(blueprint_text) for ch in all_chapters: if ch["chapter_number"] == target_chapter_number: return ch # 默认返回 return { "chapter_number": target_chapter_number, "chapter_title": f"第{target_chapter_number}章", "chapter_role": "", "chapter_purpose": "", "suspense_level": "", "foreshadowing": "", "plot_twist_level": "", "chapter_summary": "" }