如何使用正则匹配并保留 HTML 标签的完整结构进行文本分割

本文介绍如何通过正则表达式精准匹配成对的 html 标签(如 `

  • ...
  • `、`
      ...
    ` 等),在保持标签完整性的同时实现语义化切分,避免 `re.split()` 破坏标签结构的问题。

    在处理 HTML 片段时,若目标是“按特定成对标记切分字符串并保留标签本身”,直接使用 re.split() 会将分隔符(即标签)从结果中移除,导致结构丢失。例如,用 re.split(r'

  • |
      ', s) 会把
      • 当作分界点丢弃,无法满足“保留完整标签块”的需求。

        正确做法是改用 re.finditer() 或 re.findall() 进行匹配(match)而非分割(split),并构造能捕获开闭标签配对 + 中间内容的正则模式。推荐使用如下表达式:

        import re
        
        pattern = r"<(p|li|ul|ol|dl|h1|h2|h3|h4|h5|h6)>[^<]*"
        test_string = '

        Some text some text.

        Another text

        .
      • some list
      • .
          another list
        ' matches = [match.group(0) for match in re.finditer(pattern, test_string, re.DOTALL)] print(matches) # 输出: # ['

        Some text some text.

        ', '

        Another text

        ', '
      • some list
      • ', '
          another list
        ']

        该正则核心解析如下:

        • (p|li|ul|ol|dl|h1|h2|h3|h4|h5|h6):限定支持的标签名(可按需增删);
        • >[^:匹配 >,随后是非 与前面捕获组相同的内容(\1 实现标签名回溯),最后是 >。

        ⚠️ 注意事项:

        • 此方案仅适用于简单、格式良好、无嵌套、无属性、无自闭合标签(如 )的 HTML 片段
        • [^
        • 若输入含属性(如 ...)或换行/空白复杂,该正则将无法匹配;
        • 生产环境强烈建议使用专业 HTML 解析器(如 BeautifulSoup 或 lxml),它们能稳健处理真实 HTML 的所有边界情况。

        ✅ 推荐替代方案(BeautifulSoup 示例):

        from bs4 import BeautifulSoup
        
        soup = BeautifulSoup(test_string, 'html.parser')
        target_tags = soup.find_all(['p', 'li', 'ul', 'ol', 'dl', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'])
        result = [str(tag) for tag in target_tags]

        综上:正则匹配成对标签是快速原型开发的有效手段,但应明确其局限性;涉及真实 HTML 处理时,请优先选用 DOM 解析器,兼顾健壮性与可维护性。