You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PDF章节提取异常:正则提取到目录而非目标管理报告章节求助

解决默克年报合并管理报告提取错误(目录而非目标章节)的方案

问题根源

当前代码提取到目录而非目标章节,核心原因有三点:

  • 起始正则匹配到了目录中的Group Management Report条目,而非正文章节的标题
  • 循环逻辑找到第一个结束标记就直接返回,未跳过目录里的Consolidated Financial Statements链接
  • min_mdna_length的筛选逻辑未生效,因为提前返回了短内容的区间

具体改进方案

1. 优化正则,精准匹配正文章节标题

年报目录与正文的标题通常有格式差异,可利用分页符(\f,多数PDF转文本工具会生成)、页码或全大写格式来区分:

# 匹配带分页符的正文标题(适配多数转文本结果)
item7_regex = re.compile(r"\fGroup\s+Management\s+Report\f", re.DOTALL)
# 或匹配带页码的正文标题(比如正文标题前有14页的页码)
item7_regex = re.compile(r"\n14\s+Group\s+Management\s+Report\n", re.DOTALL)
# 或匹配全大写的正文标题(部分年报正文标题会全大写)
item7_regex = re.compile(r"\nGROUP\s+MANAGEMENT\s+REPORT\n", re.DOTALL)

2. 调整提取逻辑,筛选符合长度要求的区间

修改代码,遍历所有可能的起始和结束位置,仅返回长度达标且位于正文区间的内容:

def extract_mdna(plain_text: str, min_mdna_length=25000):
    # 获取所有可能的起始匹配
    start_matches = list(item7_regex.finditer(plain_text))
    if not start_matches:
        return None
    
    for start_match in start_matches:
        start_pos = start_match.start()
        # 获取起始位置之后的所有结束匹配
        end_matches = list(item8_regex.finditer(plain_text, start_pos + 1))
        for end_match in end_matches:
            end_pos = end_match.start()
            content_len = end_pos - start_pos
            # 仅返回长度达标内容
            if content_len >= min_mdna_length:
                return plain_text[start_pos:end_pos]
    return None

3. 利用页码精准锁定目标区间

目标章节位于第14-228页,可先通过页码定位文本范围,再在范围内提取章节:

def extract_mdna_by_page(plain_text: str):
    # 匹配第14页的起始位置
    page14_match = re.search(r"\n14\s+", plain_text)
    if not page14_match:
        return None
    page_start = page14_match.start()
    
    # 匹配第229页的起始位置(作为章节结束的边界)
    page229_match = re.search(r"\n229\s+", plain_text, page_start)
    if not page229_match:
        return None
    page_end = page229_match.start()
    
    # 在页码区间内匹配章节标题
    section_start = item7_regex.search(plain_text, page_start, page_end)
    section_end = item8_regex.search(plain_text, section_start.start() if section_start else page_start, page_end)
    
    if section_start and section_end:
        return plain_text[section_start.start():section_end.start()]
    return None

4. 验证转文本文件的格式差异

打开转后的文本文件,对比目录与正文的标题格式:

  • 正文标题可能带有特殊标记(如换行、分页符、全大写)
  • 目录条目通常带有后续页码(如Group Management Report 14),可在正则中排除这种格式:
    # 排除目录中带页码的条目
    item7_regex = re.compile(r"Group\s+Management\s+Report(?!\s+\d+)", re.DOTALL)
    

内容的提问来源于stack exchange,提问作者Limps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:35:39