如何用 Python 正则表达式跨多行提取指定分隔符之间的内容(排除注释行)-Python教程

本文详解如何使用 `re` 模块正确匹配跨越多行的文本块,重点解决因换行符、贪婪匹配和标志误用导致的 `nonetype` 错误,并提供健壮、可复用的正则方案。

在处理配置文件、日志片段或嵌入式脚本块时,常需提取两个固定分隔符(如 start_of_compile 和 end_of_compile)之间的全部内容,同时忽略纯注释行(如仅含 # 的行)。但直接使用 re.match() 配合 re.MULTILINE 往往失败——根本原因在于:re.MULTILINE 仅影响 ^ 和 $ 的行为(使其匹配每行首尾),而无法让 . 匹配换行符;真正需要的是 re.DOTALL(即 re.S)。

此外,原始正则存在多个关键问题:

  • 错误假设起始行为纯 # 行(实际是 #####start_of_compile… 连续出现);
  • 使用贪婪 .* 易导致跨段匹配(如匹配到下一个 end_of_compile 之后);
  • match() 要求从字符串开头严格匹配,但文件开头可能有空白或 BOM,应改用 search() 更鲁棒。

✅ 推荐解决方案(兼顾准确性与可读性):

import re

def extract_compile_block(filepath: str) -> str:
    with open(filepath, "r", encoding="utf-8") as f:
        content = f.read()

    # 关键:启用 re.DOTALL 让 . 匹配换行符;使用非贪婪 .*? 防止过度匹配
    pattern = r'#+start_of_compile[^#]*#.*?\n(.*?)\n#+end_of_compile[^#]*#'
    match = re.search(pattern, content, re.DOTALL | re.IGNORECASE)

    if not match:
        raise ValueError("Failed to locate start_of_compile / end_of_compile block")

    # 去除首尾空白,并过滤掉纯 '#' 行(保留含实际内容的行)
    inner_text = match.group(1).strip()
    lines = [line.rstrip() for line in inner_text.split('\n') 
             if line.strip() and not line.strip().startswith('#')]
    return '\n'.join(lines)

# 使用示例
try:
    result = extract_compile_block("compile.qel")
    print(result)
except (FileNotFoundError, ValueError) as e:
    print(f"Error: {e}")

? 关键要点总结:

夏夕资源网专注于CMS网站模板,主流语言整站网站源码下载,网站建设相关教程分享,好用的软件素材整合下载,提供一站式便捷自助服务。
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"zy.lucklyus.top",如遇到无法解压的请联系管理员!
夏夕资源网-网站模板_免费源码_资源素材 » 如何用 Python 正则表达式跨多行提取指定分隔符之间的内容(排除注释行)-Python教程
在线时间:12:00 - 22:00
关注微信公众号:微信公众号
站长邮箱:[email protected]
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4001136+
  • 本周更新: 0+
  • 最后更新: 2026-03-16

本站指数

×
  • 运营天数: 1392+
  • 资源总数: 47989+
  • 用户总数: 1+
  • 今日更新: 0+
  • 访问次数: 4001136+
  • 本周更新: 0+
  • 最后更新: 2026-03-16