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

基于Python Fitz的PDF工具:如何提取含关键词的完整句子

问题描述

开发一款针对标准化法律文档(无图片、无特殊字符)的PDF内容提取工具,需求如下:

  • 搜索指定关键词,返回包含该关键词的完整句子
  • 根据提取的句子更新检查清单
    目前脚本仅能返回关键词所在页码,需优化以实现完整句子提取,推测可通过分隔符提取句号间内容。现有代码如下:
import fitz
import re 

search_word = ("x", "y", "z") 
results = {} 
docs = fitz.open("some_pdf.pdf")


for page in docs: 
     word = [w[4].lower() for w in page.get_text("word")]
     for sword in search_words: ###loops through search list###
          for word in words: ### a search word is part of a word on the page
               if sword in words: 
                    pages = results.get(sword, set()) ### gets a set of page numbers so far
                    page.add(page.number) ### adds a page number
                    resultsp[sword] = pages ### writes back to results

###REPORT OF RESULTS###
for word in results: 
     results = list(map(str, results[word])) ### returns set of page numbers 
     page_list = ",".join(results) ### adds a comma to separate page numeber 
     print("word '%s' occurs on pages %s. % (word, page_list))

###OUTPUT### 

word 'x' occurs on pages n, n+1, n+2 
word 'y' occurs on pages n, n+4, n+6  
word 'z' occurs on pages n+25, n+20
解决方案

针对需求,对代码做以下优化:

  • 直接获取整页文本而非拆分单词,便于后续按句子分割
  • 使用正则表达式匹配包含关键词的完整句子(适配法律文档以句号结尾的标准化格式)
  • 重构结果存储结构,同时记录关键词所在页码及对应句子
  • 优化输出格式,清晰展示关键词、页码及匹配到的句子

优化后的完整代码:

import fitz
import re

# 定义要搜索的关键词
search_words = ("x", "y", "z")
# 重构结果存储结构:{关键词: {页码: [句子列表]}}
results = {word: {} for word in search_words}
docs = fitz.open("some_pdf.pdf")

for page in docs:
    page_num = page.number + 1  # 页码从1开始更符合阅读习惯
    # 获取整页文本,处理换行符统一为空格
    page_text = page.get_text().replace("\n", " ").strip()
    # 遍历每个关键词
    for sword in search_words:
        # 正则匹配包含关键词的完整句子:匹配前一个句号(或文本开头)到后一个句号之间的内容
        # 用re.escape处理关键词,避免特殊字符干扰;启用IGNORECASE忽略大小写
        pattern = re.compile(r'(?:^|\. )(.*?{}.*?)(?=\. |$)'.format(re.escape(sword)), re.IGNORECASE)
        matches = pattern.findall(page_text)
        if matches:
            # 如果该页码未在当前关键词的结果中,初始化列表
            if page_num not in results[sword]:
                results[sword][page_num] = []
            # 去重后添加匹配到的句子
            unique_sentences = list(set(matches))
            results[sword][page_num].extend(unique_sentences)

# 输出结果
for word in results:
    print(f"关键词 '{word}' 的匹配结果:")
    if not results[word]:
        print("  无匹配内容\n")
        continue
    for page_num, sentences in results[word].items():
        print(f"  页码 {page_num}:")
        for idx, sentence in enumerate(sentences, 1):
            # 还原句子完整格式:开头大写+结尾补句号
            full_sentence = f"{sentence.strip().capitalize()}."
            print(f"    {idx}. {full_sentence}")
    print()
代码说明
  1. 文本获取:使用page.get_text()获取整页文本,替换换行符为空格,避免因换行导致句子拆分
  2. 正则匹配:
    • 用re.escape()处理关键词,避免特殊字符干扰正则匹配
    • 匹配规则:从文本开头或句号+空格开始,到下一个句号+空格或文本结尾结束,确保提取完整句子
    • 启用re.IGNORECASE忽略大小写,适配文档中关键词的不同大小写形式
  3. 结果存储:用嵌套字典存储,键为关键词,值为{页码: 句子列表},便于后续更新检查清单
  4. 结果输出:按关键词、页码、句子的层级展示,同时还原句子的完整格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 09:07:43