You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中按指定一级章节标题拆分文本并保留标题在各段开头的实现方案

Python中按指定一级章节标题拆分文本并保留标题在各段开头的实现方案

嗨,我来帮你搞定这个文本拆分的问题!你的需求很明确:只在**一级章节标题(## 加1-9的单个数字,比如## 1、## 2)**处拆分,把标题留在对应段落的开头,同时完全忽略像## 1.1这种带小数点的子章节。下面我给你两种靠谱的Python实现思路,都是实际项目里常用的方法,你可以按需选。


方法一:用re.split结合正向预查,简单直接

原理:我们用正则的正向预查标记拆分位置,这样split的时候不会吃掉章节标题,反而会把标题留在拆分后的下一个段落开头。正则会精准匹配一级标题,自动跳过带小数点的子章节。

import re

# 你的原始文本
raw_text = "Start of text. ## 1 Introduction This is the introduction. ## 1.1 Introduction continues. ## 2 Next part This part keeps going."

# 正则解析:
# (?=## [1-9](?!\.)) 是正向预查,意思是:
# 匹配一个"位置",这个位置后面紧跟 "## " + 1-9的单个数字,且数字后面不是小数点(排除子章节)
split_result = re.split(r'(?=## [1-9](?!\.))', raw_text)

# 处理开头的前置文本:如果开头有非章节内容(比如示例里的"Start of text."),和第一个章节块合并
if len(split_result) >= 2 and split_result[0].strip():
    split_result[0] = split_result[0] + split_result.pop(1)

# 输出结果验证
for idx, part in enumerate(split_result, 1):
    print(f"=== 第 {idx} 个拆分块 ===")
    print(part.strip())  # strip()清理多余空格,按需保留或删除

运行后你会得到完全符合需求的结果:

  1. 第一个块是开头前置文本 + ##1的内容 + ##1.1的子章节内容
  2. 第二个块是##2的完整内容
    而且完全不会在##1.1的位置拆分,完美匹配你的要求!

方法二:用re.findall直接匹配目标块,更省心

原理:直接用正则写出我们想要的每个块的规则,一次性匹配出所有结果,不需要后续合并处理,适合追求逻辑清晰的场景。

import re

raw_text = "Start of text. ## 1 Introduction This is the introduction. ## 1.1 Introduction continues. ## 2 Next part This part keeps going."

# 正则解析:
# 分两种情况匹配:
# 1. (?:^.*?(?=## [1-9](?!\.)))?## [1-9](?!\.).*?(?=## [1-9](?!\.))
#    匹配「开头到第一个一级标题的内容 + 该一级标题到下一个一级标题前的所有内容」
# 2. ## [1-9](?!\.).*
#    匹配「最后一个一级标题到文本结尾的所有内容」
# re.DOTALL 让.能匹配换行符,即使你的文本有换行也不影响
blocks = re.findall(
    r'(?:^.*?(?=## [1-9](?!\.)))?## [1-9](?!\.).*?(?=## [1-9](?!\.))|## [1-9](?!\.).*',
    raw_text,
    re.DOTALL
)

# 输出结果
for idx, block in enumerate(blocks, 1):
    print(f"=== 第 {idx} 个拆分块 ===")
    print(block.strip())

这个方法会直接返回你需要的所有块,不需要额外处理开头文本,正则已经帮你把前置内容和第一个章节合并好了。如果你的文本有多个一级章节(比如##1、##2、##3),它也能自动拆分出对应的3个块,每个块都包含自己的一级标题和所有子章节内容。


一些实用的细节调整建议

  • 如果需要匹配更大范围的一级标题数字(比如0-99),把正则里的[1-9]改成\d+,同时保留(?!\.)排除子章节即可
  • 如果章节标题格式有细微变化(比如##后面有多个空格、数字后面是换行),把## 改成##\s+(匹配任意数量的空白字符)
  • 示例里的strip()是为了清理多余空格,如果你需要保留原始的空格和换行,直接去掉这个方法就行

两种方法都能完美解决你的问题,你可以根据自己的代码风格选择,第一种更灵活,第二种更直接。如果还有其他格式细节要调整,随时改正则就行,正则的弹性很大~

火山引擎 最新活动